我如何在 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 更改为 NormalMaximized 并且其图标应基于 WindowState.
  • 关闭按钮应该调用 Close() 方法 and/or Application.Current.Shutdown(0) 方法。
  • 您还应该订阅 MouseLeftButtonDownMouseLeftButtonUpMouseMove 等事件以移动 window。

您必须使用 WindowChrome class:

创建您的自定义 window chrome

WPF 中的 Window 元素实际上托管在 non-WPF (non-client) 主机中。这个宿主包括标题栏(caption)和标准按钮、一个图标和实际框架。这被称为 window chrome.

通常只能修改一个Window的客户区。但是在WindowChromeclass的帮助下,WPF允许客户区扩展到non-client区。
缺点是您必须基本上复制原始 non-client 区域才能保留原始外观。但毕竟你仍然会得到一些基本的行为,比如在双击框时最大化 window。

以下示例非常基础,但应该能让您了解如何完成您的任务:

我强烈建议按照提供的 link 到 WindowChrome class 并阅读备注部分,其中包含非常有价值的信息。
您可以使用静态 SystemParameters class 提供的实际系统值来获取当前维度值,例如SystemParameters.WindowResizeBorderThickness 您应该在自定义 chrome 样式中使用它。

另请注意,要允许 WPF 在您自定义 chrome 的输入元素(如按钮或菜单)上捕获鼠标事件,您必须在每个相关元素上设置附加的 属性 WindowChrome.IsHitTestVisibleInChrometrue:

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="&#xE921;" />
                  </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="&#xE922;" />
                  </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="&#xE8BB;" />
                  </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>