在XAML中,是否可以设置一种样式,以有选择地影响控件?

10
<Window.Resources>中,我定义了以下样式:
    <Style x:Key="textBlockStyle" TargetType="TextBlock">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>

我定义了一些网格,其中包含四个 TextBlocks

    <WrapPanel>
        <TextBlock Style="{StaticResource textBlockStyle}">Server</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">IP</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">Port</TextBlock>
        <TextBlock Style="{StaticResource textBlockStyle}">Status</TextBlock>
    </WrapPanel>

问题: 我需要四次引用textBlockStyle

问题: 是否可以在WrapPanel或其他地方仅设置一次该样式,而不必重复引用该样式?

也许可以像这样:

    <WrapPanel Style="{StaticResource textBlockStyle}">
        <TextBlock>Server</TextBlock>
        <TextBlock>IP</TextBlock>
        <TextBlock>Port</TextBlock>
        <TextBlock>Status</TextBlock>
    </WrapPanel>

我不是在寻找全局解决方案! 我可以删除x:Key="textBlockStyle"属性,但这会影响窗口中的所有TextBlocks。我需要一种更有选择性的机制,但又不希望出现丑陋的代码重复。

2个回答

17

你有几个选项,以下按照扩展性排序:

选项1:在较低级别上定义样式而不使用关键字

你可以将资源放置在WrapPanel级别,这样它只会影响WrapPanel内部的控件:

<WrapPanel>
    <WrapPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Margin" Value="5,0,5,0"/>
        </Style>
    </WrapPanel.Resources>

    <!-- TextBlocks here -->
</WrapPanel>

请注意缺少键值。这个 Style 将应用于 WrapPanel 内所有的 TextBlock

选项2:在较高级别上使用键定义Style,然后在较低级别上再次定义不带键的Style

如果您在较高级别上定义了具有键的 Style,那么您可以在较低级别上定义另一个不带键的 Style,并基于较高级别的样式定义该 Style

<Window>
    <Window.Resources>
        <Style TargetType="TextBlock" x:Key="textBlockStyle">
            <Setter Property="Margin" Value="5,0,5,0"/>
        </Style>
    </Window.Resources>

    <WrapPanel>
        <WrapPanel.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle"/>
        </WrapPanel.Resources>

        <!-- TextBlocks here -->
    </WrapPanel>
</Window>
这将导致WrapPanel内部的TextBlock自动应用Style,但在它之外的不会。此外,您不需要重复Style的详细信息 - 它们存储在更高级别上。
选项3:将样式放在ResourceDictionary中并进行选择性合并
最后,您可以将Style放在单独的ResourceDictionary中,并将该字典有选择地合并到控件的Resources集合中:
<!-- TextBlockStyles.xaml -->
<ResourceDictionary>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>
</ResourceDictionary>

<!-- Window.xaml -->
<Window>
    <WrapPanel>
        <WrapPanel.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="TextBlockStyles.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </WrapPanel.Resources>
    </WrapPanel>
</Window>

<!-- Alternative Window.xaml if you have only one RD to merge in -->
<Window>
    <WrapPanel>
        <WrapPanel.Resources>
            <ResourceDictionary Source="TextBlockStyles.xaml"/>
        </WrapPanel.Resources>
    </WrapPanel>
</Window>

现在您可以定义任意多个样式集合并将它们选择性地应用于您的元素树。


如果我已经定义了样式并在其他地方使用它,通常我会更喜欢选项2,否则选择选项1。就这个问题而言,Kent的回答非常好。 - Bryan Anderson

2
是的,你可以做到。你几乎有正确的思路了。要这样做....
<WrapPanel>
< WrapPanel. Resources >
<Style TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="5,0,5,0"/>
    </Style>
</WrapPanel.Resources/>
        <TextBlock Server</TextBlock>
        <TextBlock >IP</TextBlock>
        <TextBlock >Port</TextBlock>
        <TextBlock >Status</TextBlock>
    </WrapPanel>

通过使用{x:type }语法,您无需x:key即可为wrappanel中的所有文本块设置样式。如果您需要不同的样式,仍然可以使用x:key并明确在文本块上设置样式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接