如何有效地设置StaticResourceExtension的数据上下文?
本文关键字:数据 上下文 StaticResourceExtension 有效地 设置 | 更新日期: 2023-09-27 18:18:29
我正在努力减少代码重复。考虑以下内容:
<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"传递给第二个commonItem实例?
我意识到在上面的例子中应该有更好的方法来做到这一点,这是XAML中真正发生的事情的一个非常精简的版本。
更一般的问题是,我如何遵循良好的DRY原则,当我有上下文菜单在整个应用程序是不同的,但共享一些类似的菜单项?
首先,您不应该将MenuItem
放在Resources
中。这将只创建一个MenuItem的单个实例,因为它是一个UIElement
,它只能在你的页面上的一个位置使用。
你可以在你的资源中保留一个菜单项的Style
,与大多数菜单项共同的所有设置,并将该样式应用于你的项目。提示:如果你从Style
中省略x:Key
,只给它一个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>
所以在做了一些研究之后,我意识到我的设计太复杂了。以下是我所做的:
添加自定义菜单项类型:
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派生类型。