Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

.net - Is it possible to set a style in XAML that selectively affects controls?

In <Window.Resources> I have defined following style:

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

I have defined some grid where I have four 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>

Problem: I need to reference the textBlockStyle four times.

Question: Is it possible to set that style just once at in WrapPanel or somewhere else without repeating the reference to the style?

Maybe something like:

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

I am not searching for a global solution! I could delete that x:Key="textBlockStyle" property, but that would affect all TextBlocks in the Window. I need a more selective mechanism, but without that ugly code duplication.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have several options, presented here in order of how well they scale.

Option 1: Define the Style without a key at a lower level

You can stick the resource at the WrapPanel level so that it only affects controls inside that WrapPanel:

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

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

Notice the lack of key. This Style will apply to all TextBlocks within the WrapPanel.

Option 2: Define the Style with a key and again without at a lower level

If you define the Style at a higher level with a key, you can then define another Style at a lower level without a key, and base that Style on the higher level one:

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

This results in a Style being automatically applied to TextBlocks inside the WrapPanel, but not outside it. Also, you don't duplicate the details of the Style - they are stored at a higher level.

Option 3: Place the Styles in a ResourceDictionary and selectively merge it

Finally, you can place your Styles in a separate ResourceDictionary and selectively merge that dictionary into a control's Resources collection:

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

Now you can have as many style sets defined in separate dictionaries as you like, and then selectively apply them to your element tree.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...