我如何在 Window 栏中获得菜单?
How do i get a Menu in the Window bar?
我想知道如何在 window 栏中获取菜单,与 Visual studio 一样。
最好能在左边有文件、编辑等按钮,在右边有标准的最小化、最大化和关闭按钮。这完全可能吗?
我试过设置 Window
WindowStyle="None"
并在栏中添加我自己的图标,但似乎不正确,但这是唯一的方法吗?
这就是我目前的情况。
<Window
Title="MainWindow"
Height="{x:Static SystemParameters.PrimaryScreenHeight}"
Width="{x:Static SystemParameters.PrimaryScreenWidth}"
Closing="Window_Closing"
WindowState="Maximized">
标题栏包含
- 一个图标
- 一个标题
- 一个最小化按钮
- 最大化按钮
- 关闭按钮
仅此而已。你不能添加任何东西。
在 VS 中,标题栏被屏蔽了。你看到的“标题栏”其实就是window的内容。也就是说,正如您所怀疑的那样,这是唯一的方法。
这也是为什么大多数应用程序右侧三个按钮上的工具提示使用 OS 语言(因为标题栏由系统管理),但使用 Visual Studio.[=24= 的应用程序语言]
您必须将 WindowStyle
设置为 None
以屏蔽真正的标题栏。
然后,在您的 window 中,您应该添加一个 DockPanel
并停靠在顶部左侧的图像和菜单,以及右侧的 3 个按钮。
- 最小化按钮应将
WindowState
更改为 Minimized
。
- 最大化按钮应将
WindowState
更改为 Normal
或 Maximized
并且其图标应基于 WindowState
.
- 关闭按钮应该调用
Close()
方法 and/or Application.Current.Shutdown(0)
方法。
- 您还应该订阅
MouseLeftButtonDown
、MouseLeftButtonUp
和 MouseMove
等事件以移动 window。
您必须使用 WindowChrome
class:
创建您的自定义 window chrome
WPF 中的 Window
元素实际上托管在 non-WPF (non-client) 主机中。这个宿主包括标题栏(caption)和标准按钮、一个图标和实际框架。这被称为 window chrome.
通常只能修改一个Window
的客户区。但是在WindowChrome
class的帮助下,WPF允许客户区扩展到non-client区。
缺点是您必须基本上复制原始 non-client 区域才能保留原始外观。但毕竟你仍然会得到一些基本的行为,比如在双击框时最大化 window。
以下示例非常基础,但应该能让您了解如何完成您的任务:
我强烈建议按照提供的 link 到 WindowChrome
class 并阅读备注部分,其中包含非常有价值的信息。
您可以使用静态 SystemParameters class 提供的实际系统值来获取当前维度值,例如SystemParameters.WindowResizeBorderThickness
您应该在自定义 chrome 样式中使用它。
另请注意,要允许 WPF 在您自定义 chrome 的输入元素(如按钮或菜单)上捕获鼠标事件,您必须在每个相关元素上设置附加的 属性 WindowChrome.IsHitTestVisibleInChrome
到 true
:
WindowChrome.IsHitTestVisibleInChrome="True"
创建上述视觉效果的最基本样式如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework">
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome NonClientFrameEdges="Right"
ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Background="Transparent">
<AdornerDecorator>
<Border Background="Transparent" Margin="{x:Static SystemParameters.WindowNonClientFrameThickness}">
<ContentPresenter />
</Border>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
<Grid Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
Background="#FF3F3F3F"
VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Custom window chrome -->
<StackPanel Grid.Column="0" Orientation="Horizontal"
Margin="{x:Static SystemParameters.WindowResizeBorderThickness}">
<Image Source="{TemplateBinding Icon}" />
<TextBlock Text="{TemplateBinding Title}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="16,0" />
<Menu shell:WindowChrome.IsHitTestVisibleInChrome="True">
<MenuItem Header="CustomChromeMenu">
<MenuItem Header="Action" />
</MenuItem>
</Menu>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTip="Minimize window"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Maximize window"
Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Close application"
ToolTipService.ShowDuration="5000"
Width="50"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
</StackPanel>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
我想知道如何在 window 栏中获取菜单,与 Visual studio 一样。
最好能在左边有文件、编辑等按钮,在右边有标准的最小化、最大化和关闭按钮。这完全可能吗?
我试过设置 Window
WindowStyle="None"
并在栏中添加我自己的图标,但似乎不正确,但这是唯一的方法吗?
这就是我目前的情况。
<Window
Title="MainWindow"
Height="{x:Static SystemParameters.PrimaryScreenHeight}"
Width="{x:Static SystemParameters.PrimaryScreenWidth}"
Closing="Window_Closing"
WindowState="Maximized">
标题栏包含
- 一个图标
- 一个标题
- 一个最小化按钮
- 最大化按钮
- 关闭按钮
仅此而已。你不能添加任何东西。 在 VS 中,标题栏被屏蔽了。你看到的“标题栏”其实就是window的内容。也就是说,正如您所怀疑的那样,这是唯一的方法。 这也是为什么大多数应用程序右侧三个按钮上的工具提示使用 OS 语言(因为标题栏由系统管理),但使用 Visual Studio.[=24= 的应用程序语言]
您必须将 WindowStyle
设置为 None
以屏蔽真正的标题栏。
然后,在您的 window 中,您应该添加一个 DockPanel
并停靠在顶部左侧的图像和菜单,以及右侧的 3 个按钮。
- 最小化按钮应将
WindowState
更改为Minimized
。 - 最大化按钮应将
WindowState
更改为Normal
或Maximized
并且其图标应基于WindowState
. - 关闭按钮应该调用
Close()
方法 and/orApplication.Current.Shutdown(0)
方法。 - 您还应该订阅
MouseLeftButtonDown
、MouseLeftButtonUp
和MouseMove
等事件以移动 window。
您必须使用 WindowChrome
class:
WPF 中的 Window
元素实际上托管在 non-WPF (non-client) 主机中。这个宿主包括标题栏(caption)和标准按钮、一个图标和实际框架。这被称为 window chrome.
通常只能修改一个Window
的客户区。但是在WindowChrome
class的帮助下,WPF允许客户区扩展到non-client区。
缺点是您必须基本上复制原始 non-client 区域才能保留原始外观。但毕竟你仍然会得到一些基本的行为,比如在双击框时最大化 window。
以下示例非常基础,但应该能让您了解如何完成您的任务:
我强烈建议按照提供的 link 到 WindowChrome
class 并阅读备注部分,其中包含非常有价值的信息。
您可以使用静态 SystemParameters class 提供的实际系统值来获取当前维度值,例如SystemParameters.WindowResizeBorderThickness
您应该在自定义 chrome 样式中使用它。
另请注意,要允许 WPF 在您自定义 chrome 的输入元素(如按钮或菜单)上捕获鼠标事件,您必须在每个相关元素上设置附加的 属性 WindowChrome.IsHitTestVisibleInChrome
到 true
:
WindowChrome.IsHitTestVisibleInChrome="True"
创建上述视觉效果的最基本样式如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework">
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome NonClientFrameEdges="Right"
ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Background="Transparent">
<AdornerDecorator>
<Border Background="Transparent" Margin="{x:Static SystemParameters.WindowNonClientFrameThickness}">
<ContentPresenter />
</Border>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
<Grid Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
Background="#FF3F3F3F"
VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Custom window chrome -->
<StackPanel Grid.Column="0" Orientation="Horizontal"
Margin="{x:Static SystemParameters.WindowResizeBorderThickness}">
<Image Source="{TemplateBinding Icon}" />
<TextBlock Text="{TemplateBinding Title}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="16,0" />
<Menu shell:WindowChrome.IsHitTestVisibleInChrome="True">
<MenuItem Header="CustomChromeMenu">
<MenuItem Header="Action" />
</MenuItem>
</Menu>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTip="Minimize window"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Maximize window"
Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Close application"
ToolTipService.ShowDuration="5000"
Width="50"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
</StackPanel>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>