wpf自定义标题栏系列
第一章 自定义标题栏
第二章 添加窗口阴影
第三章 style中定义标题栏(本章)
第四章 style使用参数及模板定义标题栏
前言
本文是《C# wpf 一种style中调用cs代码的方法》的示例,同时也是《C# wpf 自定义标题栏及无边框窗口》的完善,将标题栏及无边框放到了style中,且实现了放大缩小关闭按钮以及拖动功能。这样在一个项目中有多个窗口需要使用自定义无边框效果,就可以直接复用即可,省去了每个窗口都要添加相同的界面和逻辑代码。
一、如何实现?
1.定义资源字典
添加一个名为WindowStyles资源字典。
定义窗口无边框的Style样式根据《C# wpf 自定义标题栏及无边框窗口》的窗口中的代码转化成Style即可。
示例如下:
<Style x:Key="WindowStyle_Normal_Gray" TargetType="Window">
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--标题栏-->
<Grid Background="Gray" Height="50" >
<!--省略-->
</Grid>
<!--客户区-->
<ContentPresenter Grid.Row="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2.定义cs文件
定义一个与资源字典名称相同的cs文件,WindowStyles.xaml.cs。
如下:
在WindowStyles.xaml.cs文件中定义按钮的command,可以在WindowStyles的静态构造方法中实现具体逻辑。
public class WindowStyles
{
//关闭窗体
public static ICommand CloseWindowCommand
{
get;
private set;
}
//最小化窗体
public static ICommand MinimizeWindowCommand
{
get;
private set;
}
//最大化窗体
public static ICommand MaximizeWindowCommand
{
get;
private set;
}
}
还要实现鼠标拖动功能,根据《C# wpf 一种style中调用cs代码的方法》定义一个用于初始化的附加属性,名称为IsDragMoveable。在PropertyChangedCallback中实现拖动逻辑。
示例如下:
//由于style中不能给事件赋值,但是可以在附加属性改变事件中获取控件对象,此时再给控件事件赋值。
public static bool GetIsDragMoveable(DependencyObject obj)
{
return (bool)obj.GetValue(IsDragMoveableProperty);
}
public static void SetIsDragMoveable(DependencyObject obj, bool value)
{
obj.SetValue(IsDragMoveableProperty, value);
}
// Using a DependencyProperty as the backing store for IsDragMoveable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsDragMoveableProperty =
DependencyProperty.RegisterAttached("IsDragMoveable", typeof(bool), typeof(WindowStyles), new PropertyMetadata(false,PropertyChangedCallback));
3.资源字典中关联cs代码
关闭按钮
<Button Command="{x:Static local:WindowStyles.CloseWindowCommand}"\>
最小化按钮
<Button Command="{x:Static local:WindowStyles.MinimizeWindowCommand}"\>
最大化按钮
<Button Command="{x:Static local:WindowStyles.MaximizeWindowCommand}"\>
鼠标拖动
<!--标题栏-->
<Grid local:WindowStyles.IsDragMoveable="True" >
二、使用方法
引用资源字典后,直接给style赋值即可,但是要注意的是,在Window中引用资源字典只能使用DynamicResource关联style。
<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:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="720" Width="1280"
Style="{DynamicResource WindowStyle_Normal_Gray}"
>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Background="White">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#999999" FontSize="128" Text="Hello Word!"></TextBlock>
</Grid>
</Window>
效果预览
三、完整代码
https://download.csdn.net/download/u013113678/35730298
总结
本文讲述了一种在style中自定义标题栏无边框窗口的方法。其内部的实现其实没那么简单,尤其是实现按钮逻辑以及拖动逻辑,需要在style中关联cs代码,这就要求我们熟悉绑定技巧、附加属性还有ContentPresenter 。但是好处也是明显的,及时具有了通用性,无论是哪个窗体都可以使用。