文本框上下文菜单中未应用WPF菜单项样式

文本框上下文菜单中未应用WPF菜单项样式,wpf,xaml,textbox,menuitem,wpf-style,Wpf,Xaml,Textbox,Menuitem,Wpf Style,我曾经创建了一个样式来修复WPF中菜单项的错误外观。这主要是关于菜单文本未对齐的问题。它在左上角太远,没有使用适当的间距 我发现它确实在窗口菜单中起作用,但在我现在测试的TextBox的上下文菜单中不起作用。所以问题是,为什么这种风格不适用于文本框中的上下文菜单 更新:我发现TextBox使用它自己的菜单项类,一个私有嵌套类TextEditorContextMenu.EditorContextMenu和它自己的菜单项,嵌套类EditorMenuItem。它们分别来自ContextMenu和Men

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

我发现它确实在窗口菜单中起作用,但在我现在测试的
TextBox
的上下文菜单中不起作用。所以问题是,为什么这种风格不适用于文本框中的上下文菜单

更新:我发现
TextBox
使用它自己的菜单项类,一个私有嵌套类
TextEditorContextMenu.EditorContextMenu
和它自己的菜单项,嵌套类
EditorMenuItem
。它们分别来自
ContextMenu
MenuItem
。所以,如果它们是我设计的类的一个子类,那么为什么我的样式不也应用于它们呢

我唯一能做的就是复制

<ControlTemplate x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type MenuItem}, ResourceId=SubmenuItemTemplateKey}" TargetType="{x:Type MenuItem}">

您的问题在于不清楚WPF中的样式是如何工作的。有两种风格处理方式不同

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

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

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

internal void GetRawValue(DependencyProperty dp、PropertyMetadata、ref EffectiveValueEntry)
{
// ...
if(dp!=StyleProperty)
{
if(StyleHelper.GetValueFromStyleOrTemplate(新的FrameworkObject(this,null),dp,ref条目))
{
返回;
}
}
其他的
{
目标源;
object implicitValue=FrameworkElement.FindImplicitStyleResource(this,this.GetType(),out source);
if(隐式值!=DependencyProperty.UnsetValue)
{
//此样式已从参考资料中获取
HasImplicitStyleFromResources=true;
entry.BaseValueSourceInternal=BaseValueSourceInternal.ImplicitReference;
entry.Value=implicitValue;
返回;
}
}
// ...
}
因此,您的
样式
没有被应用,因为它只为
菜单项
类设计,因为它不是主题
样式
。有两种方法可以更改
文本框
上下文菜单
中项目的
样式
,它们都有缺点

第一种方法是为所有
文本框添加
样式
,并在其中设置
上下文菜单
。但如果分别使用文本服务框架和拼写检查,您将失去reconversion和speller
MenuItems

<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>

您是否尝试过通过绑定到StaticResource样式来手动添加样式?你只需要给你的风格一个键,然后写一些类似style=“{StaticResource MenuStyle}”的东西。我认为应该行得通。还有一个“OverwritedFault”——我想是风格上的属性。我不知道你的意思。谢谢。我已经看到了第一段代码,但它对于非英语环境也不好,因为您需要使用本地化的菜单文本。(嗯,这里的文本实际上缺失了,这是否意味着它是自动本地化的?)最后一段代码实际上解决了我的问题。顺便问一下,菜单上的“再转换”是什么?我看到它在浏览框架代码,但找不到它的作用。是的,它们将自动本地化,因为如果未设置
标题
属性,则
MenuItem
类使用
RoutedUICommand.Text
属性。要理解什么是再转换,请阅读并备注。
<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>