首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF MenuItem样式不应用于TextBox上下文菜单。

WPF MenuItem样式不应用于TextBox上下文菜单。
EN

Stack Overflow用户
提问于 2016-01-21 09:42:54
回答 1查看 1.9K关注 0票数 1

我曾经创建了一个样式来修复WPF中菜单项被窃听的外观。它主要是关于菜单文本不对齐的。它在左上角太远,没有使用适当的间距。

我发现它确实在窗口菜单中工作,但是在我现在测试的的上下文菜单中,不是。所以问题是,为什么文本框中的上下文菜单不考虑这种样式?

更新:我发现TextBox使用自己的菜单项类、私有嵌套类TextEditorContextMenu.EditorContextMenu和自己的菜单项--嵌套类EditorMenuItem。两者都来自于ContextMenuMenuItem,resp。那么,如果它们是我所设计的类的子类,那么为什么我的风格也不适用于它们呢?

我唯一能做的就是复制

代码语言:javascript
复制
<ControlTemplate x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type MenuItem}, ResourceId=SubmenuItemTemplateKey}" TargetType="{x:Type MenuItem}">

从PresentationFramework.Aero的资源到我的样式文件。但是,这使得我的菜单看起来很像Windows 7,这在Windows 8或10 (或XP)上可能不是预期的。但是重新定义样式键至少会影响EditorMenuItem的外观。为什么?

如果EditorMenuItem没有自己的样式(我找不到它),为什么它不使用我为基类提供的任何样式?它怎么知道不使用我的样式,而只使用默认的样式,而默认的样式是被替换的,对于其他每个上下文菜单都是不可访问的?

下面是XAML代码,它存储在MenuStyles.xaml中,并包含在来自App.xaml的ResourceDictionary中。

代码语言:javascript
复制
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- Expression Blend 4 created this (and a lot more) from some system theme on Windows 7 -->
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
        <Style.Triggers>
            <Trigger Property="Role" Value="TopLevelHeader">
                <Setter Property="Padding" Value="7,2,8,3"/>
                <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
            </Trigger>
            <Trigger Property="Role" Value="TopLevelItem">
                <Setter Property="Padding" Value="7,2,8,3"/>
                <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
            </Trigger>
            <Trigger Property="Role" Value="SubmenuHeader">
                <Setter Property="Padding" Value="5,4,2,3"/>
                <!-- Changed from 2,3,2,3 -->
                <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
            </Trigger>
            <Trigger Property="Role" Value="SubmenuItem">
                <Setter Property="Padding" Value="5,4,2,3"/>
                <!-- Changed from 2,3,2,3 -->
            </Trigger>
        </Style.Triggers>
    </Style>

    <!-- Expression Blend 4 created this from some system theme on Windows 7 -->
    <!-- Edited like in: http://devlicio.us/blogs/christopher_bennage/archive/2008/06/19/styling-separators-in-wpf.aspx -->
    <!-- Decreased in height to be more platform standard -->
    <Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="{x:Type Separator}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Separator}">
                    <Grid Margin="0,3,0,2" SnapsToDevicePixels="true">
                        <!-- Changed from 0,6,0,4 -->
                        <Rectangle Fill="#E0E0E0" Height="1" Margin="30,0,1,1"/>
                        <Rectangle Fill="White" Height="1" Margin="30,1,1,0"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-24 11:12:14

您的问题在于不清楚地了解WPF中的样式是如何工作的。有两种类型的样式处理方式不同。

第一种类型是主题风格。每个FrameworkElementFrameworkContentElement在初始化时使用DefaultStyleKey属性解析自己的Style。带有主题资源的资源字典的位置由ThemeInfoAttribute指定。

第二种类型是非主题风格。可以通过指定元素的Style属性显式设置此样式。或者也可以在初始化时隐式地解析它。非主题样式的Setter优先于主题样式的Setter

当您通过将非主题Style添加到应用程序或没有键的元素的ResourceDictionary中时,它将隐式地使用,并且只有没有显式设置Style属性的目标类型的实例才会受到影响,而不是派生类型。此行为在FrameworkElement.GetRawValue方法(第1887行)中定义:

代码语言:javascript
复制
internal void GetRawValue(DependencyProperty dp, PropertyMetadata metadata, ref EffectiveValueEntry entry)
{
    // ...

    if (dp != StyleProperty)
    {
        if (StyleHelper.GetValueFromStyleOrTemplate(new FrameworkObject(this, null), dp, ref entry))
        {
            return;
        }
    }
    else
    {
        object source;
        object implicitValue = FrameworkElement.FindImplicitStyleResource(this, this.GetType(), out source);
        if (implicitValue != DependencyProperty.UnsetValue)
        {
            // This style has been fetched from resources
            HasImplicitStyleFromResources = true;

            entry.BaseValueSourceInternal = BaseValueSourceInternal.ImplicitReference;
            entry.Value = implicitValue;
            return;
        }
    }

    // ...
}

因此,您的Style没有应用,因为它只为MenuItem类设计,因为它不是主题Style。您有两种方法来更改StyleTextBox's ContextMenu中的项,它们都有缺点。

第一种方法是为所有的Style es添加一个TextBox,并在其中设置ContextMenu。但是,如果分别使用和拼写检查,则将释放重转换和拼写MenuItems

代码语言:javascript
复制
<Style TargetType="{x:Type TextBox}">
    <Setter Property="ContextMenu">
        <Setter.Value>
            <ContextMenu>
                <MenuItem Command="ApplicationCommands.Copy" />
                <MenuItem Command="ApplicationCommands.Cut" />
                <MenuItem Command="ApplicationCommands.Paste" />
            </ContextMenu>
        </Setter.Value>
    </Setter>
</Style>

第二种方法是在启动时使用反射为TextEditorContextMenu.EditorMenuItem类创建一个TextEditorContextMenu.EditorMenuItem。但是,只有在使用拼写检查和文本服务框架时,才应该使用此方法。

代码语言:javascript
复制
// Inside the Application.OnStartup method
Style menuItemStyle = TryFindResource(typeof(MenuItem)) as Style;
if (menuItemStyle != null)
{
    Assembly menuItemAssembly = typeof(MenuItem).Assembly;
    Type editorMenuType = menuItemAssembly.GetType("System.Windows.Documents.TextEditorContextMenu+EditorMenuItem", false);
    if (editorMenuType != null)
    {
        Resources.Add(editorMenuType, menuItemStyle);
    }

    Type reconversionMenuType = menuItemAssembly.GetType("System.Windows.Documents.TextEditorContextMenu+ReconversionMenuItem", false);
    if (reconversionMenuType != null)
    {
        Resources.Add(reconversionMenuType, menuItemStyle);
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34920125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档