我正在尝试减少代码重复。请考虑以下事项:
<page...>
<page.resources>
<MenuItem x:Key="commonItem" />
</page.resources>
<TextBlock>
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.Resources>
<local:thingOne x:Key="one"/>
<local:thingTwo x:Key="two"/>
</ContextMenu.Resources>
<StaticResourceExtension PropertyKey="commonItem"/>
<StaticResourceExtension PropertyKey="commonItem"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</page>
如何将“one”传递给第一个commonItem实例,将“two”传递给第二个?
我知道,鉴于上面的例子,有更好的方法可以做到这一点,这是我们的XAML中真正发生的一个非常精简的版本。
更普遍的问题是,当我在不同的应用程序中有上下文菜单但共享一些类似的菜单项时,如何遵循良好的DRY原则?
答案 0 :(得分:1)
首先,您不应在MenuItem
中添加Resources
。这只会创建一个MenuItem的单个实例,因为它是UIElement
,它只能在您的页面上的一个位置使用。
您可以为资源中的MenuItem保留Style
,其中包含大多数MenuItem通用的所有设置,并将该样式应用于您的项目。提示:如果您忽略x:Key
中的Style
而只是给它TargetType
,则会将其应用于所有 MenuItems
:
<Page...>
<Page.resources>
<Style TargetType="MenuItem" >
<Setter Property="Header" Value="{Binding}" />
<Setter Property="Foreground" Value="Lime" />
</Style>
</Page.resources>
<TextBlock>
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.Resources>
<local:thingOne x:Key="one"/>
<local:thingTwo x:Key="two"/>
</ContextMenu.Resources>
<MenuItem DataContext="{StaticResource one}" />
<MenuItem DataContext="{StaticResource two}" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</Page>
答案 1 :(得分:0)
经过一番研究,我意识到自己太过复杂了。这是我做的:
添加自定义菜单项类型:
public class MyMenuItem : MenuItem {}
在适当的范围内容中(对我而言,它是全球性的):
<Style TargetType="namespace:MyMenuItem">
<!-- common control internals -->
</Style>
需要使用时:
<ContextMenu>
<ContextMenu.Resources>
<local:thingOne x:Key="one"/>
<local:thingTwo x:Key="two"/>
</ContextMenu.Resources>
<namespace:MyMenuItem DataContext={Binding one}/>
<namespace:MyMenuItem DataContext={Binding two}/>
</ContextMenu>
此方法允许设置DataContext,并允许在与需要具有不同行为的MenuBase控件中的其他MenuItem结合时自动样式应用。
可以预期可以应用命名样式,并且可以使用简单的菜单项。我试过了,但没用。我希望在某个地方有一些东西覆盖了MenuItem,但不适用于MenuItem派生类型。