在 WPF 中设置嵌套元素的样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/666269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:10:50  来源:igfitidea点击:

Styling nested elements in WPF

wpfnestedstyleschildren

提问by gix

Suppose you have a nested element structure, for example a ContextMenu with MenuItems:

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

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

You can easily apply styles or templates to the ContextMenu or MenuItem elements. But if the MenuItem style belongs to the Menu style it is quite cumbersome and redundant to add it to every MenuItem element.

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

Is there any way to apply those automatically to child elements? So that you can simply write this:

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

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

It would be neat if FooMenuStyle could style containing MenuItem elements, but that does not seem to be possible.

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

Edit: The Menu example is probably misleading since I was unaware of ItemContainerStyle and the intent was for a general solution. Based on the two answers I have come up with two solutions: one general variant and one for ItemContainerStyle and the like:

编辑:菜单示例可能具有误导性,因为我不知道 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>

采纳答案by Josh G

<ContextMenu>
   <ContextMenu.Resources>
      <Style TargetType="{x:Type MenuItem}">
         <!--Setters-->
      </Style>
   </ContextMenu.Resources>
   <MenuItem/>
   <!--Other MenuItems-->
</ContextMenu>

The style will be applied to all MenuItem objects within the ContextMenu.

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

回答by Juan Calero

Just to complete the original answer, I think it is clearer adding the nested style inside the parent like that:

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

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

回答by Kent Boogaart

<ContextMenu ItemContainerStyle="{StaticResource FooMenuItemStyle}">
    <MenuItem/>
</ContextMenu>