【发布时间】:2016-04-08 13:47:45
【问题描述】:
我对 ContextMenu 有这种隐含的风格,我从 this site 那里得到:
<Application.Resources>
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
<Style TargetType="ContextMenu">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border
Name="Border"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1" >
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="true">
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3"/>
<Setter TargetName="Border" Property="CornerRadius" Value="4"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
然后我尝试在这里使用它,以便它同时应用于TextBox 的默认ContextMenu 和我为Button 添加的ContextMenu。
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Height="30" Width="200">Test</TextBox>
<Button Grid.Row="1" Width="200" Height="30" Content="Test2">
<Button.ContextMenu>
<ContextMenu>
<MenuItem>Test</MenuItem>
<MenuItem>Test2</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
样式会应用于Button,但不会应用于TextBox。
我觉得这应该是相当直接和简单的,为什么我的隐式风格没有应用到TextBox 的默认ContextMenu,我做错了什么?
==更新==
目前我不确定答案,但我认为这里的问题是TextBox 和ContextMenu 的设计存在一些缺陷,我希望有更多知识的人能够确认。
使用 Snoop 我可以看到 ContextMenu 不是您所期望的对象,而是一个 EditorContextMenu 对象,它是内部的,因此您无法设置它的样式。他们为什么使用它?我不知道。
作为一种解决方法,我创建了一个默认上下文菜单并使用它。如果您向TextBox 添加上下文菜单,它会正确地采用隐式样式。
既然你知道默认ContextMenu有的item,而item又基本使用ApplicationCommands,就很简单了:
<ContextMenu x:Key="DefaultContextMenu">
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>
然后在你的 TextBoxStyle 中做:
<Style x:Key="MyTextBoxStyle" TargetType="TextBox">
<Setter Property="ContextMenu" Value="{StaticResource DefaultContextMenu}" />
这样,您的TextBox 的默认ContextMenu 将采用隐式样式。
【问题讨论】:
-
您的资源字典在哪里?在某处有像
<Style TargetType="ContextMenu" BasedOn="{StaticResource {x:Type ContextMenu}}" />这样的行,您只需更改 basedon 值即可将您的新样式引用为全局默认值。 -
@ChrisW。 - 对不起,我不明白。正如您在我的代码中看到的,我在应用程序资源中定义了
ContextMenu的隐式样式:<Style TargetType="ContextMenu">。我尝试将它添加到不同的级别,但在任何级别中都不起作用。 -
您找到解决问题的方法了吗?我有同样的问题:(
-
@mgarant - 没有人回答为什么会这样,从使用 snoop 来看,它似乎在设计中存在一些缺陷,但我找到了解决方法,我将其作为更新发布。