【问题标题】:How do i get a Menu in the Window bar?如何在窗口栏中获得菜单?
【发布时间】:2021-05-31 06:31:20
【问题描述】:

我想知道如何在窗口栏中获取菜单,和 Visual Studio 一样。

如果能够在左侧有文件、编辑等,在右侧有标准的最小化、最大化和关闭按钮,那就太好了。这有可能吗?

我尝试设置 Window WindowStyle="None" 并在栏中添加我自己的图标,但这似乎不对,但这是唯一的方法吗?

这是我目前拥有的。

<Window
        Title="MainWindow" 
        Height="{x:Static SystemParameters.PrimaryScreenHeight}"
        Width="{x:Static SystemParameters.PrimaryScreenWidth}"
        Closing="Window_Closing"
        WindowState="Maximized">

【问题讨论】:

  • 不幸的是,标题栏不可配置。它是窗口样式的一部分。它只能完全删除并替换为您自己的样式。例如,这里建议:stackoverflow.com/a/68465633/13349759

标签: c# wpf xaml window


【解决方案1】:

您必须使用WindowChrome 类创建自定义窗口镶边:

WPF 中的Window 元素实际上托管在非 WPF(非客户端)主机中。该主机包括标题栏(标题)和标准按钮、图标和实际框架。这称为窗口镶边。

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

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

我强烈建议按照提供的链接到WindowChrome 课程并阅读备注部分,其中包含非常有价值的信息。
您可以使用静态 SystemParameters 类提供的实际系统值来获取当前维度值,例如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="&#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>

【讨论】:

    【解决方案2】:

    标题栏包含

    • 图标
    • 标题
    • 最小化按钮
    • 最大化按钮
    • 关闭按钮

    仅此而已。你不能添加任何东西。 在 VS 中,标题栏是被屏蔽的。你看到的“标题栏”其实就是窗口的内容。也就是说,正如您似乎怀疑的那样,这是唯一的方法。 这也是为什么三个右侧按钮上的工具提示在大多数应用程序中使用操作系统语言(因为标题栏由系统管理),但在 Visual Studio 中使用应用程序语言。

    您必须将WindowStyle 设置为None 才能掩盖真实的标题栏。 然后,在您的窗口中,您应该添加一个DockPanel 并在顶部停靠一个图像和一个左侧的菜单,以及右侧的 3 个按钮。

    • 最小化按钮应将WindowState 更改为Minimized
    • 最大化按钮应将WindowState 更改为NormalMaximized,其图标应基于WindowState
    • 关闭按钮应调用Close() 方法和/或Application.Current.Shutdown(0) 方法。
    • 您还应该订阅MouseLeftButtonDownMouseLeftButtonUpMouseMove 等事件来移动窗口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多