内容简介:根据观察,这个溢出宽度应该是不管使用哪种方法,最大化时,系统的标题栏高度都发生了变化,故,需要重新设置模板中定义的标题栏高度。
博客分类: FAQ
注意:
-
本文方法基础是WindowChrome,而WindowChrome在
.NET Framework 4.5
之后才集成发布的。见: WindowChrome Class -
在
.NET Framework 4.0
中使用WindowChrome,需要安装 Ribbon 来支持 WindowChrome -
目前官方文档的内容较为陈旧(但仍有参考价值),其中提到了
SystemParameters2
,这个应该是Ribbon里的东西,4.5
想用可以安装Xceed.Wpf.AvalonDock
库,这里面有现成的Microsoft.Windows.Shell.SystemParameters2
实现——当然,自己不怕麻烦,可以自己实现来获取要用的系统变量。(一般用不着,4.5
中SystemParameters
添加了许多系统变量的实现)
实现步骤
第一步:基本实现【保留系统基础操作按钮】
- 添加Window的Style定义,并设置WindowChrome.WindowChrome属性;
-
设置WindowChrome标题栏:
- CaptionHeight——主要用于拖动有效区;
- GlassFrameThickness——影响标题栏系统按钮显示,0表示不使用系统按钮【后面介绍】,-1表示用的系统默认值,如下示例则表示标题栏高度30;
- 自定义窗体Title
注意:控件模板中的定义:
- 1、最外层Border背景无颜色,否则会覆盖标题栏,看不到系统按钮。
- 2、内部布局定义,使用Grid隔出30的标题栏高度,也可以直接对ContentPresenter设置Margin【主要是为了让顶部显示出标题栏】。
<Style x:Key="WindowStyle1" TargetType="{x:Type Window}"> <Setter Property="WindowChrome.WindowChrome"> <Setter.Value> <WindowChrome CaptionHeight="30" GlassFrameThickness="0,30,0,0"/> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Window}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" > <AdornerDecorator > <Grid> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <ContentPresenter Grid.Row="1"/> <TextBlock Text="{TemplateBinding Title}" HorizontalAlignment="Left" VerticalAlignment="Center" /> </Grid> </AdornerDecorator> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
存在的问题: 最大化边框问题 —— 会有部分溢出。
根据观察,这个溢出宽度应该是 8
,此值的来源: (SystemParameters.MaximizedPrimaryScreenWidth - SystemParameters.WorkArea.Width)/2
,高度也可以这样计算。
第二步:优化边界处理
- 方法1:模板添加最大化触发器,设置最大化时,内部布局Margin设为8
- 方法2:模板添加最大化触发器,设置最大化时,限制布局最大化的宽高最大值
不管使用哪种方法,最大化时,系统的标题栏高度都发生了变化,故,需要重新设置模板中定义的标题栏高度。
<ControlTemplate TargetType="{x:Type Window}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" > <AdornerDecorator > <Grid Name="win_content"> <Grid.RowDefinitions> <RowDefinition Height="30" x:Name="row_title"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <ContentPresenter Grid.Row="1"/> <TextBlock Text="{TemplateBinding Title}" HorizontalAlignment="Left" VerticalAlignment="Center" /> </Grid> </AdornerDecorator> </Border> <ControlTemplate.Triggers> <Trigger Property="WindowState" Value="Maximized"> <Setter Property="Margin" TargetName="win_content" Value="8"/> <!--二选一--> <Setter Property="MaxWidth" TargetName="win_content" Value="{Binding Source={x:Static SystemParameters.WorkArea},Path=Width}" /> <Setter Property="MaxHeight" TargetName="win_content" Value="{Binding Source={x:Static SystemParameters.WorkArea},Path=Height}"/> <Setter Property="Height" TargetName="row_title" Value="22" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
至此,都是系统标题栏和我们自定义内容组合使用,但这样总有些边边角角要修正,下面就完全自定义标题栏
第三步:完全自定义标题栏【即,不使用系统的操作按钮】
-
初步操作类似第一步,其中将
GlassFrameThickness
设置为0
-
在内容定义部分添加自定义的标题栏,添加操作按钮,并设置按钮属性
WindowChrome.IsHitTestVisibleInChrome="True"
如果不设置 WindowChrome.IsHitTestVisibleInChrome
,则由于我们之前设置 CaptionHeight
,则这个区域内,按钮将失效。
但是,也不能将整个标题栏布局设置这个属性,那样会完全覆盖系统标题栏的操作,如拖动效果,即 CaptionHeight
设置的那个区域。
<!--样式定义--> <Style x:Key="WindowStyle2" TargetType="{x:Type Window}"> <Setter Property="WindowChrome.WindowChrome"> <Setter.Value> <WindowChrome UseAeroCaptionButtons="False" GlassFrameThickness="0" CaptionHeight="30" /> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Window}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" > <AdornerDecorator > <ContentPresenter x:Name="win_content" /> </AdornerDecorator> </Border> <ControlTemplate.Triggers> <Trigger Property="WindowState" Value="Maximized"> <Setter Property="Margin" TargetName="win_content" Value="8"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
<!--定义标题栏--> <Grid Background="Red" > <Grid Height="30" HorizontalAlignment="Stretch" VerticalAlignment="Top" Background="Blue"> <StackPanel Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True" HorizontalAlignment="Right" > <Button Name="btn_Min" Content="—" ></Button> <Button Name="btn_Max" Content="☐" ></Button> <Button Name="btn_Close" Content="✕" ></Button> </StackPanel> </Grid> </Grid>
//标题栏按钮功能实现 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.btn_Min.Click += Btn_Min_Click; this.btn_Max.Click += Btn_Max_Click; this.btn_Close.Click += Btn_Close_Click; } private void Btn_Close_Click(object sender, RoutedEventArgs e) { this.Close(); } private void Btn_Max_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Maximized == this.WindowState ? WindowState.Normal : WindowState.Maximized; } private void Btn_Min_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Minimized; } }
关联了解:
如果你平时也使用Visual Studio Code【VSCode】,文中的第一步和第三步,在vscode的设置中有对应效果:
- 第一步 —— 将vscode用户设置中Title Bar Style值设为native;
- 第三步 —— 将vscode用户设置中Title Bar Style值设为custom。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- WPF中窗体最大化问题处理
- c# – 防止Winform最大化?
- 最大化超融合基础设施优势的十大建议
- 详解 CRP:如何最大化提升首屏渲染速度
- 信任帮助智能分析释放潜力 让员工最大化利用智能技术提高效率优化见解
- 【ICLR 2019论文】互信息最大化的无监督图神经网络Deep Graph Infomax
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图片转BASE64编码
在线图片转Base64编码工具
随机密码生成器
多种字符组合密码