14

我已经在 WPF 中工作了很长一段时间,但是有一些关于样式的基本知识我只是不明白。

如何设置Menu控件的前景色和背景色?我从这个开始:

    <Menu IsMainMenu="True" Background="#FF3A3A3A" Foreground="White">
        <MenuItem Header="_File">
            <MenuItem Header="_Exit">
            </MenuItem>
        </MenuItem>
    </Menu>

前景色显然是由 继承的MenuItem,但背景不是。下一次尝试:

    <Menu IsMainMenu="True" Background="#FF3A3A3A" Foreground="White">
        <MenuItem Background="#FF3A3A3A" Header="_File">
            <MenuItem Header="_Exit">
            </MenuItem>
        </MenuItem>
    </Menu>

现在,当菜单被激活时,突出显示/覆盖颜色不正确,我看不到设置它们的明显属性。此外,菜单弹出窗口有一个宽的白色边框,我也不知道如何更改它的颜色(或大小)。

我错过了什么?

4

2 回答 2

29

您将希望了解有关 WPF 中的模板和样式的更多信息(实际上是 XAML)。在 XAML 中,控件的外观和控件的操作方式是完全不同的两件事。在您的示例中,您可能具有 Foreground 和 Background 属性,但控件的样式\模板不能利用这些属性来显示控件。

阅读http://wpftutorial.net/Templates.htmlhttp://wpftutorial.net/TemplatesStyles.html,它们会给你一个很好和快速的概述。如需更深入的了解,请阅读以下内容:http: //msdn.microsoft.com/en-us/library/ee230084.aspx

如果您使用 Visual Studio 2012 编辑您的 WPF UI,您可以轻松地创建菜单控件正在使用的样式\模板的副本,然后对其进行编辑。如果您使用的是 Visual Studio 2010,您应该下载并安装(它可能是免费的,也可能不是免费的)Expression Blend 以编辑您的 XAML UI。

提示:如果您使用的是 Visual Studio 2012,请确保您的文档大纲窗口窗格始终可见。这对于编辑 XAML UI 非常方便。我的默认折叠在程序的左侧。默认情况下,此窗格在 Expression Blend 中可见。

在 Document Outline 中找到 MenuItem 控件。右键单击它并选择编辑模板->编辑副本...

这将创建菜单项现有外观的副本以供您编辑。当您这样做时,您将处于该模板的编辑模式,要“弹出”该模式,请单击“文档大纲”窗口左上角的小图标。

返回范围按钮

编辑模板时,您可以看到模板的布局和设计。当菜单项作为下拉部分时,它实际上像弹出菜单(右键菜单)一样显示。浏览该模板,我立即弹出的是名为 SubMenuBackgroundBrush 的颜色资源:

<SolidColorBrush x:Key="SubMenuBackgroundBrush" Color="#FFF5F5F5"/>

如果您搜索 SubMenuBackgroundBrush,您可以看到它用于名为 PART_Popup 的部件:

<Popup x:Name="PART_Popup" AllowsTransparency="true" Focusable="false" HorizontalOffset="1" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" VerticalOffset="-1">
    <Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent">
        <Border x:Name="SubMenuBorder" BorderBrush="#FF959595" BorderThickness="1" Background="{StaticResource SubMenuBackgroundBrush}">
            <ScrollViewer x:Name="SubMenuScrollViewer" Margin="1,0" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                <Grid RenderOptions.ClearTypeHint="Enabled">
                    <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                        <Rectangle x:Name="OpaqueRect" Fill="{StaticResource SubMenuBackgroundBrush}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
                    </Canvas>
                    <Rectangle Fill="#F1F1F1" HorizontalAlignment="Left" Margin="1,2" RadiusY="2" RadiusX="2" Width="28"/>
                    <Rectangle Fill="#E2E3E3" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
                    <Rectangle Fill="White" HorizontalAlignment="Left" Margin="30,2,0,2" Width="1"/>
                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="true" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                </Grid>
            </ScrollViewer>
        </Border>
    </Themes:SystemDropShadowChrome>
</Popup>

这是您在右键单击显示菜单或下拉菜单的内容时看到的弹出窗口。将引用从:更改{StaticResource SubMenuBackgroundBrush}{TemplateBinding Foreground}

运行程序时,您会看到弹出窗口的主背景发生了变化,但显示图标的区域没有变化。这些也是<Rectangle Fill="弹出控件中的所有项目。也改变那些。最后一个对 Rectangle 的引用看起来像是分割图标和文本的线,您可能无法更改它。

享受美妙的模板世界。它看起来令人困惑,并且需要大量工作。这是。但是当你掌握它的窍门时,它是一个非常酷的系统。掌握了窍门后,很难再回到任何其他 UI 系统。

于 2012-12-09T02:03:20.980 回答
4

我错过了什么?

控件或多或少是可自定义的,并且有两个级别的自定义控件:

  1. 在放置控件的 XAML 中设置 、 等Foreground属性。Background
  2. Template在你的控件中设置Style,并创建你自己的ControlTemplate.

第二个涉及更多,但它提供了更大的灵活性,使控件看起来像你想要的那样。如果是这种情况,听起来这就是您所需要的。查看Menu 和 MenuItem 的默认 ControlTemplate。您可以复制/粘贴它们并根据需要进行修改。

<Window.Resources>
    <Style TargetType="{x:Type Menu}">
        <Setter Property="Template">
            <ControlTemplate TargetType="{x:Type Menu}">
                <!-- your modified template here -->
            </ControlTemplate>
        </Setter>
    </Style>
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Template">
            <ControlTemplate TargetType="{x:Type MenuItem}">
                <!-- your modified template here -->
            </ControlTemplate>
        </Setter>
    </Style>
</Window.Resources>
于 2012-12-09T02:04:34.283 回答