2020年8月31日星期一

WPF 使用WindowChrome自定义窗体 保留原生窗体特性

本文大幅度借鉴dino.c大佬的文章

https://www.cnblogs.com/dino623/p/uielements_of_window.html

https://www.cnblogs.com/dino623/p/problems_of_WindowChrome.html

https://www.cnblogs.com/dino623/p/custom_window_style_using_WindowChrome.html

我在这里汇总一下,属于粘了就能用那种。在预设100,125,150,175DPI下最大化也能正常显示。

不懂的地方可以阅读上面的文章

说到原生窗体的特性都有什么 咱来做个对比 大家来感受下

使用WindowChrome

使用Window

使用WindowChrome的时候 无需设置就保留了原生阴影、拖拽、交互动画

而使用Window的话,会发现最大化的时候会覆盖任务栏。

想要实现原生的样式就需要自己手写。

这些功能可以实现吗?能实现。效果好吗? 不一定,像我这种WPF玩的不专业的人很难实现这些功能,啥玩意都得上网扒拉,对不对路还不一定,那百度上一人一种写法,这就很闹心。

<Window x:Class="WpfApp1.MainWindow"  ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  ="http://schemas.microsoft.com/winfx/2006/xaml"  ="http://schemas.microsoft.com/expression/blend/2008"  ="http://schemas.open  mc:Ignorable="d"  Title="MainWindow" SnapsToDevicePixels="True" StateChanged="Window_StateChanged" Loaded="Window_Loaded"> <WindowChrome.WindowChrome>  <WindowChrome UseAeroCaptionButtons="False" NonClientFrameEdges="None" CaptionHeight="40" /> </WindowChrome.WindowChrome> <Grid x:Name="grdMain" Background="Transparent">  <Grid.RowDefinitions>   <RowDefinition Height="40"/>   <RowDefinition Height="*"/>  </Grid.RowDefinitions>  <Grid Grid.Row="0" Background="#C62F2F">   <WrapPanel Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,10,0">    <Button x:Name="btnMin" Style="{DynamicResource MinButton}" Click="BtnMin_Click"/>    <Button x:Name="btnNorm" Style="{DynamicResource MaxButton}" Margin="3,0,0,0" Click="BtnNorm_Click"/>    <Button x:Name="btnClose" Style="{DynamicResource CloseButton}" Margin="3,0,0,0" Click="BtnClose_Click"/>   </WrapPanel>  </Grid>  <Grid Grid.Row="1" Background="#FFFFFF">   <Border BorderThickness="1" BorderBrush="#C62F2F"/>  </Grid> </Grid></Window>

UseAeroCaptionButtons 表示是对 Windows Aero 标题按钮启用的命中测试是否可用,默认值为True。

NonClientFrameEdges 获取或设置一个值,该值表示窗口框架边缘是否归客户端所有,默认值为None。

CaptionHeight 表示窗体菜单栏高度,我这里设置跟Gird里第一行高度一致,代表自定义的菜单栏。

注意下,我在放置按钮的WrapPanel容器中设置了 WindowChrome.IsHitTestVisibleInChrome,该值表示 WPF 命中测试在窗口非工作区中的元素是否可用,默认值为False。

接下来是后台代码

using System;using System.Windows;using System.Windows.Controls;using System.Windows.Input;namespace WpfApp1{ /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window {  int paddings = 0;  public MainWindow()  {   InitializeComponent();  }  private void Window_Loaded(object sender, RoutedEventArgs e)  {   paddings = 4;  }  private void Window_StateChanged(object sender, EventArgs e)  {   if (WindowState == WindowState.Maximized)   {    Thickness thickness = SystemParameters.WindowResizeBorderThickness;    grdMain.Margin = new Thickness(thickness.Left + paddings, thickness.Top + paddings, thickness.Right + paddings, thickness.Bottom + paddings);   }   else   {    grdMain.Margin = new Thickness(0);   }  }  private void BtnMin_Click(object sender, RoutedEventArgs e)  {   WindowState = WindowState.Minimized;  }  private void BtnClose_Click(object sender, RoutedEventArgs e)  {   Close();  }  private void BtnNorm_Click(object sender, RoutedEventArgs e)  {   if (WindowState == WindowState.Normal)   {    btnNorm.Style = (Style)FindResource("NormButton");    WindowState = WindowState.Maximized;   }   else   {    btnNorm.Style = (Style)FindResource("MaxButton");    WindowState = WindowState.Normal;   }  } }}

这里的paddings我默认设置为4,这里需要借鉴下大佬的第一、二篇文章,里面很清晰的解释道为啥设置为4。

完整看过第二篇文章的会发现无法直接获取SM_CXPADDEDBORDER的值。

我查了官网文档user32.dll里面有函数可以取值。https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-getsystemmetrics

[DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetSystemMetrics(int index);

只不过按照这个取值来的话125往上的DPI最大化显示不正常,边框会比之前厚,咱就默认4就行。

WPF 使用WindowChrome自定义窗体 保留原生窗体特性易联通拍拍购物美菜产品满足亚马逊秒杀条件却没被推荐?可能是这些原因onward旺季亚马逊索评邮件还能这样写,简单又实用!扒皮|| 这位被粉丝撕上热搜、挂名大骂滚出美妆圈的网红到底是何方神圣?欧洲VAT危机持续发酵,欧洲市场掘金不易!

没有评论:

发表评论

跨境电商资讯:外贸宣传平台有哪些(出口的

现在很多做外贸的人都非常关注 外贸企业怎么推广 ,而现在推广的途径和平台有很多,企业如果都做,成本和时间精力是一个问题,而且并不是所有的推广渠道都是有用的。今天云程网络就来为大家盘点几个有效的外贸推广渠道。 一、海外社交媒体营销 Facebook,领英等海外社交媒体营销在近几年得...