一、概述
桌面应用,设计要求不同的标题颜色并且窗口有一定的阴影效果。开始是基于wpf做的应用,后续因为有系统需求所以迁移至avaloniaUi,通过查阅资料实现了需求效果,所以记录下方便自己后续查阅。
二、WPF标题栏
通过类WindowChrome使你能够将Windows Presentation Foundation (WPF) 内容扩展到通常为操作系统的窗口管理器保留的窗口的非工作区。主要设置两个属性 WindowStyle、ResizeBorderThickness,也可以通过模板进行修改设置。
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow"
Height="450" Width="800"
WindowStyle="None">
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="2"/>
</WindowChrome.WindowChrome>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Gray" MouseDown="Grid_MouseDown">
<TextBlock Text="MainWindow"/>
</Grid>
<Grid Grid.Row="1"></Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Input;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton!=MouseButtonState.Pressed)
return;
this.DragMove();
}
}
}
三、AvaloniaUi标题栏
特别注意:WindowState
与ShowInTaskbar
属性同时出现,一定一定要将WindowState
属性放置在ShowInTaskbar
属性之前。不然win11左下角会有窗,并且初始化时重新配置WindowState
属性,不然win7左下角会有窗口,如下
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="MainWindow"
WindowState="Minimized"
CanResize="False"
Topmost="True"
IsVisible="True"
ShowInTaskbar="False"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"
SystemDecorations="None">
</Window>
...
public MainWindow()
{
InitializeComponent();
WindowState = WindowState.Minimized
}
...
方式一、属性配置
主要设置属性:
ExtendClientAreaTitleBarHeightHint
:设置为0隐藏标题栏按钮(最大最小化、关闭)。
注:windows10 按钮看不见但依旧有效且无阴影效果
ExtendClientAreaToDecorationsHint
:内容扩展至标题栏
MainWindow.axaml
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaApplication1.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:AvaloniaApplication1.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaApplication1"
ExtendClientAreaTitleBarHeightHint="0"
ExtendClientAreaToDecorationsHint="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Gray" PointerPressed="Grid_PointerPressed">
<TextBlock Text="MainWindow"/>
</Grid>
<Grid Grid.Row="1">
<views:MainView />
</Grid>
</Grid>
</Window>
MainWindow.axaml.cs
using Avalonia.Controls;
namespace AvaloniaApplication1.Views;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Grid_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
{
BeginMoveDrag(e);
}
}
方式二、模板控件(自定义窗体)
通过模板控件统一窗体样式,并添加window控件基础类统一基础事件
BaseWindow.axaml
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:AvaloniaApplication1.Views">
<Design.PreviewWith>
<controls:BaseWindow Height="200" Width="400" />
</Design.PreviewWith>
<Style Selector="Window">
<Setter Property="SystemDecorations" Value="None"/>
<Setter Property="Template">
<ControlTemplate>
<Border BorderBrush="#DCDCDC" BorderThickness="1" Background="White"
Height="{Binding BorderHeight,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}"
Width="{Binding BorderWidth,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}">
<Border.Effect>
<DropShadowEffect BlurRadius="30" Opacity="0.2" Color="black"/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Name="TitlePanel" Background="Gray">
<Image Source="{Binding TitleIcon}" Height="25" Width="25"/>
<TextBlock Text="{TemplateBinding Title}"
Margin="5,0,0,0"
VerticalAlignment="Center"/>
</Grid>
<ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
</Styles>
BaseWindow.axaml.cs
{
public class BaseWindow : Window
{
//有这个才能渲染出来
protected override Type StyleKeyOverride => typeof(Window);
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Grid? titlePanel = e.NameScope.Find<Grid>("TitlePanel");
if (titlePanel != null) titlePanel.PointerPressed += Grid_PointerPressed;
}
private void Grid_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
{
BeginMoveDrag(e);
}
public Bitmap? TitleIcon
{
get
{
if (Icon == null) return null;
Stream stream = new MemoryStream();
Icon.Save(stream);
return new Bitmap(stream);
}
}
//使用时一定要设置宽度
public new double Width
{
get => GetValue(WidthProperty);
set
{
SetValue(WidthProperty, GetWidthHeightValue(value));
BorderWidth = value;
}
}
//使用时一定要设置高度
public new double Height
{
get => GetValue(HeightProperty);
set
{
SetValue(HeightProperty, GetWidthHeightValue(value));
BorderHeight = value;
}
}
/// <summary>
/// 获取宽高值,仅win10预留阴影位置
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private double GetWidthHeightValue(double value)
{
return Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major == 10 && Environment.OSVersion.Version.Build < 2200 ? value + 40 : value;
}
public double BorderHeight { get; set; }
public double BorderWidth { get; set; }
}
}
App.axaml 引用模板样式
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaApplication1.App"
RequestedThemeVariant="Light">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme />
<StyleInclude Source="/Views/BaseWindow.axaml"/>
</Application.Styles>
</Application>
Comments NOTHING