0

我正在尝试减少代码重复。考虑以下:

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

如何将“一个”传递给第一个 commonItem 实例,将“两个”传递给第二个?

我意识到给定上面的例子会有更好的方法来做到这一点,这是我们 XAML 中实际发生的事情的一个非常精简的版本。

更普遍的问题是,当我在整个应用程序中都有不同的上下文菜单但共享一些相似的菜单项时,我如何遵循良好的 DRY 原则?

4

2 回答 2

1

首先,你不应该MenuItem在你的Resources. 这只会创建一个 MenuItem 实例,并且因为它是一个,UIElement所以它只能在您的页面上的一个位置使用。

您可以改为Style在资源中为 MenuItem 保留 a,使用大多数 MenuItem 共有的所有设置,并将该样式应用于您的项目。提示:如果您省略x:Keyfrom yourStyle并只给它 a 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>
于 2013-06-15T21:47:12.017 回答
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 派生类型。

于 2013-06-16T21:38:42.297 回答