【问题标题】:Styling nested elements in WPF在 WPF 中设置嵌套元素的样式
【发布时间】:2010-10-14 13:19:40
【问题描述】:

假设您有一个嵌套的元素结构,例如带有 MenuItems 的 ContextMenu:

<ContextMenu Style="{StaticResource FooMenuStyle}">
    <MenuItem Style="{StaticResource FooMenuItemStyle}"/>
    ...
</ContextMenu>

您可以轻松地将样式或模板应用于 ContextMenu 或 MenuItem 元素。但是,如果 MenuItem 样式属于 Menu 样式,则将其添加到每个 MenuItem 元素中是非常麻烦和多余的。

有没有办法自动将这些应用到子元素?这样你就可以简单地写这个:

<ContextMenu Style="{StaticResource FooMenuStyle}">
    <MenuItem/>
    ...
</ContextMenu>

如果 FooMenuStyle 可以设置包含 MenuItem 元素的样式,那就太好了,但这似乎是不可能的。

编辑:Menu 示例可能具有误导性,因为我不知道 ItemContainerStyle 并且其意图是提供通用解决方案。基于这两个答案,我提出了两种解决方案:一种是通用变体,一种是 ItemContainerStyle 等:

<Style x:Key="FooMenuItem" TargetType="{x:Type MenuItem}">
    ...
</Style>

<Style x:Key="FooMenu" TargetType="{x:Type ContextMenu}">
    <!-- Variant for specific style attribute -->
    <Setter Property="ItemContainerStyle"
            Value="{StaticResource FooMenuItem}"/>

    <!-- General variant -->
    <Style.Resources>
        <Style TargetType="{x:Type MenuItem}"
               BasedOn="{StaticResource FooMenuItem}"/>
    </Style.Resources>
</Style>

<ContextMenu Style="{StaticResource FooMenu}">
    <MenuItem/>
</ContextMenu>

【问题讨论】:

    标签: wpf nested styles children


    【解决方案1】:

    只是为了完成原始答案,我认为在父级内部添加嵌套样式会更清楚:

    <Style x:Key="WindowHeader" TargetType="DockPanel" >
        <Setter Property="Background" Value="AntiqueWhite"></Setter>
        <Style.Resources>
            <Style TargetType="Image">
                <Setter Property="Margin" Value="6"></Setter>
                <Setter Property="Width" Value="36"></Setter>
                <Setter Property="Height" Value="36"></Setter>
            </Style>
            <Style TargetType="TextBlock">
                <Setter Property="TextWrapping" Value="Wrap"></Setter>
            </Style>
        </Style.Resources>
    </Style>
    

    【讨论】:

    • 这是最合适的答案。在网络上没有任何地方可以罚款。你摇滚!谢谢。
    • 谢谢,这个信息真的很难找到。
    • 我使用此示例帮助我将样式应用于嵌套在工具提示中的所有文本块 - 设置最大宽度并强制换行,以便更好地格式化长消息。
    • 这真的很有用。谢谢。
    • 作为参考,如果有人需要针对特定​​类型,可以使用DynamicResource 属性来完成,如下所述:stackoverflow.com/a/31045455
    【解决方案2】:
    <ContextMenu>
       <ContextMenu.Resources>
          <Style TargetType="{x:Type MenuItem}">
             <!--Setters-->
          </Style>
       </ContextMenu.Resources>
       <MenuItem/>
       <!--Other MenuItems-->
    </ContextMenu>
    

    样式将应用于 ContextMenu 中的所有 MenuItem 对象。

    【讨论】:

    • 我认为他的资源中已经有了样式,并希望将其应用于子项,而不是再次重新声明。
    • 而且,使用ItemContainerStyle可以更清晰的表达出来。
    • 您可以声明从以前的样式派生的新样式。
    【解决方案3】:
    <ContextMenu ItemContainerStyle="{StaticResource FooMenuItemStyle}">
        <MenuItem/>
    </ContextMenu>
    

    【讨论】:

    • 我认为我的菜单示例有点误导(因为我不知道 ItemContainerStyle),并且最初的意图是针对任意元素。但因为我实际上有一个菜单,所以这是要走的路。
    【解决方案4】:

    我完成此操作的方法是在全局资源字典中创建一个 keyed ResourceDictionaryinside,然后仅将其应用于父元素。

    在 app.xaml 中:

    <Application.Resources>
      <ResourceDictionary>
        ...
    
        <ResourceDictionary x:Key="menuChildrenStyles">
          <Style TargetType="MenuItem">
            <!--Setters-->
          </Style>
        </ResourceDictionary>
    
        ...
      </ResourceDictionary>
    </Application.Resources>
    

    然后在您的其他 xaml 视图中:

    <ContextMenu Resources="{StaticResource menuChildrenStyles}">
      <MenuItem />
      <MenuItem />
      <MenuItem />
      <MenuItem />
    </ContextMenu>
    

    这会将MenuItem 样式应用于父元素内的所有MenuItem 元素。

    您还可以将其他样式添加到“menuChildrenStyles”字典中,例如TextBlock 等。

    【讨论】:

      猜你喜欢
      • 2018-03-01
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多