WPF 基础控件之Window样式
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 基础控件之Window样式相关的知识,希望对你有一定的参考价值。
WPF开发者QQ群: 340500857
由于微信群人数太多入群请添加小编微信号
yanjinhuawechat 或 W_Feng_aiQ 邀请入群
需备注WPF开发者
PS:有更好的方式欢迎推荐。
01
—
代码如下
一、创建 Window.cs继承System.Windows.Window代码如下。
在WPF自定义类库时需要注意在创建自定义Window时 默认新建的资源文件会找不到Style导致Window打开会成为黑色窗体解决方案有两种如下:
1)通过Style的Key去资源字典找到并替换窗体元数据。
static T GetResourceKey<T>(string key)
if (Application.Current.TryFindResource(key) is T resource)
return resource;
return default;
2)直接对自定义库下的Themes文件夹下Generic.xaml资源写自定义Window的样式即可。
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
namespace WPFDevelopers.Minimal.Net45x
public class Window : System.Windows.Window
public double TitleHeight
get return (double)GetValue(TitleHeightProperty);
set SetValue(TitleHeightProperty, value);
public static readonly DependencyProperty TitleHeightProperty =
DependencyProperty.Register("TitleHeight", typeof(double), typeof(Window), new PropertyMetadata(50d));
static Window()
StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(GetResourceKey<Style>("WPFDevelopersWindow")));
static T GetResourceKey<T>(string key)
if (Application.Current.TryFindResource(key) is T resource)
return resource;
return default;
public Window()
this.Loaded += Window_Loaded;
CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));
CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));
CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));
//CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));
private void Window_Loaded(object sender, RoutedEventArgs e)
hWnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hWnd).AddHook(WindowProc);
protected override void OnContentRendered(EventArgs e)
base.OnContentRendered(e);
if (SizeToContent == SizeToContent.WidthAndHeight)
InvalidateMeasure();
#region Window Commands
private void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;
private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
e.CanExecute = ResizeMode != ResizeMode.NoResize;
private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
//Close();
SystemCommands.CloseWindow(this);
private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
SystemCommands.MaximizeWindow(this);
private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
//SystemCommands.MinimizeWindow(this);
SendMessage(hWnd, ApiCodes.WM_SYSCOMMAND, new IntPtr(ApiCodes.SC_MINIMIZE), IntPtr.Zero);
private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
SystemCommands.RestoreWindow(this);
internal class ApiCodes
public const int SC_RESTORE = 0xF120;
public const int SC_MINIMIZE = 0xF020;
public const int WM_SYSCOMMAND = 0x0112;
private IntPtr hWnd;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
if (msg == ApiCodes.WM_SYSCOMMAND)
if (wParam.ToInt32() == ApiCodes.SC_MINIMIZE)
WindowStyle = WindowStyle.SingleBorderWindow;
WindowState = WindowState.Minimized;
handled = true;
else if (wParam.ToInt32() == ApiCodes.SC_RESTORE)
WindowState = WindowState.Normal;
WindowStyle = WindowStyle.None;
handled = true;
return IntPtr.Zero;
private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
var element = e.OriginalSource as FrameworkElement;
if (element == null)
return;
var point = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight)
: new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
point = element.TransformToAncestor(this).Transform(point);
SystemCommands.ShowSystemMenu(this, point);
#endregion
二、创建资源字典Window.xaml。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfdev="clr-namespace:WPFDevelopers.Minimal.Net45x" >
<Style x:Key="WindowButtonStyle" TargetType="x:Type Button">
<Setter Property="Foreground" Value="DynamicResource PrimaryTextSolidColorBrush"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="MinWidth" Value="30"/>
<Setter Property="MinHeight" Value="28"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="PART_ContentPresenter" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="PART_ContentPresenter" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.3"
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="PART_ContentPresenter"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Fill="Transparent"/>
<ContentPresenter x:Name="PART_ContentPresenter" Opacity="0.7"
HorizontalAlignment="TemplateBinding HorizontalContentAlignment"
Margin="TemplateBinding Padding" VerticalAlignment="TemplateBinding VerticalContentAlignment"
Content="TemplateBinding Content" ContentTemplate="TemplateBinding ContentTemplate"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="WPFDevelopersWindow" TargetType="x:Type wpfdev:Window" BasedOn="x:Null">
<Setter Property="Foreground" Value="DynamicResource PrimaryTextSolidColorBrush" />
<Setter Property="Background" Value="DynamicResource WhiteSolidColorBrush" />
<Setter Property="BorderBrush" Value="DynamicResource PrimaryNormalSolidColorBrush" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="MaxHeight" Value="x:Static SystemParameters.MaximizedPrimaryScreenHeight"/>
<Setter Property="MaxWidth" Value="x:Static SystemParameters.MaximizedPrimaryScreenWidth"/>
<Setter Property="FontFamily" Value="DynamicResource NormalFontFamily" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome GlassFrameThickness="0,0,0,1"
UseAeroCaptionButtons="False"
CaptionHeight="Binding TitleHeight,RelativeSource=RelativeSource AncestorType=wpfdev:Window"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type wpfdev:Window">
<Border BorderBrush="TemplateBinding BorderBrush"
BorderThickness="TemplateBinding BorderThickness"
SnapsToDevicePixels="True">
<Grid Background="TemplateBinding Background">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="TemplateBinding TitleHeight"
Background="TemplateBinding BorderBrush">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<Image Source="TemplateBinding Icon" Stretch="Fill"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="30" Height="30" Margin="14,0,4,0"
RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Text="TemplateBinding Title" x:Name="PART_Title"
Foreground="DynamicResource WhiteSolidColorBrush" Grid.Column="1"
VerticalAlignment="Center" FontSize="DynamicResource TitleFontSize"/>
<WrapPanel Grid.Column="2" WindowChrome.IsHitTestVisibleInChrome="True">
<WrapPanel x:Name="PART_MinAndMax">
<Button Name="PART_MinimizeButton" IsTabStop="False" Padding="0" Margin="0,6"
Style="StaticResource WindowButtonStyle" ToolTip="Minimize"
Command="SystemCommands.MinimizeWindowCommand">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle x:Name="MinimizeGlyph" Width="10" Height="1" Margin="0 7 0 0"
VerticalAlignment="Bottom" Fill="DynamicResource WhiteSolidColorBrush" />
</Grid>
</Button>
<Button Name="PART_MaximizeButton" IsTabStop="False" Padding="0"
Style="StaticResource WindowButtonStyle" Margin="0,6"
ToolTip="Maximize"
Command="SystemCommands.MaximizeWindowCommand">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Width="10" Height="10"
HorizontalAlignment="Center" VerticalAlignment="Center"
Data="DynamicResource PathMetroWindowMaximize" Fill="DynamicResource WhiteSolidColorBrush"
Stretch="Fill" UseLayoutRounding="False" />
</Grid>
</Button>
<Button Name="PART_RestoreButton" IsTabStop="False" Padding="0"
Style="StaticResource WindowButtonStyle" Margin="0,6"
ToolTip="Restore"
Command="SystemCommands.RestoreWindowCommand"
Visibility="Collapsed">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Width="10" Height="10"
HorizontalAlignment="Center" VerticalAlignment="Center"
Data="DynamicResource PathMetroWindowRestore" Fill="DynamicResource WhiteSolidColorBrush"
Stretch="Fill" UseLayoutRounding="False" />
</Grid>
</Button>
</WrapPanel>
<Button Name="PART_CloseButton" Margin="0,6"
ToolTip="Close"
IsTabStop="False" Style="StaticResource WindowButtonStyle"
Command="SystemCommands.CloseWindowCommand">
<Path Width="10" Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="DynamicResource PathMetroWindowClose"
Fill="DynamicResource WhiteSolidColorBrush"
Stretch="Fill" />
</Button>
</WrapPanel>
</Grid>
<AdornerDecorator Grid.Row="1" KeyboardNavigation.IsTabStop="False"
Margin="4">
<ContentPresenter x:Name="MainContentPresenter"/>
</AdornerDecorator>
<ResizeGrip x:Name="ResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Grid.Row="2" IsTabStop="False"
Visibility="Collapsed"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="Visibility" Value="Visible" TargetName="PART_RestoreButton"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_MaximizeButton"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip" />
<Condition Property="WindowState" Value="Normal" />
</MultiTrigger.Conditions>
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="NoResize" />
<Condition Property="WindowStyle" Value="ToolWindow" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_MinAndMax" Property="Visibility" Value="Collapsed" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
三、创建MainWindow.xaml。
<ws:Window x:Class="Wpf45.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:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"
xmlns:local="clr-namespace:Wpf45"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</ws:Window>
四、删除MainWindow.xaml.cs删除继承。
public partial class MainWindow
public MainWindow()
InitializeComponent();
02
—
效果预览
鸣谢素材提供者 - 菜小松cc
源码地址如下
Github:https://github.com/WPFDevelopersOrg
Gitee:https://gitee.com/WPFDevelopersOrg
WPF开发者QQ群: 340500857
Github:https://github.com/WPFDevelopersOrg
出处:https://www.cnblogs.com/yanjinhua
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载请著名作者 出处 https://github.com/WPFDevelopersOrg
扫一扫关注我们,
更多知识早知道!
点击阅读原文可跳转至源代码
以上是关于WPF 基础控件之Window样式的主要内容,如果未能解决你的问题,请参考以下文章