Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 336
Theo Lenndorff Avatar asked Mar 29 '09 15:03

Theo Lenndorff


People also ask

How do you use style in XAML?

Apply a style implicitly You can change the default appearance by setting properties, such as FontSize and FontFamily, on each TextBlock element directly. However, if you want your TextBlock elements to share some properties, you can create a Style in the Resources section of your XAML file, as shown here.

What is style in XAML?

You can customize the appearance of your apps in many ways by using the XAML framework. Styles let you set control properties and reuse those settings for a consistent appearance across multiple controls.

What are styles in WPF?

Styles provide us the flexibility to set some properties of an object and reuse these specific settings across multiple objects for a consistent look. In styles, you can set only the existing properties of an object such as Height, Width, Font size, etc. Only default behavior of a control can be specified.


2 Answers

yup,you can do that.you almost have the right idea. you do that like this....

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

by using the {x:type } syntax you dont need the x:key,it will set the style for all textblocks in the wrappanel. if you want diff styles, you can still use the x:key and explicity set the style on the textblock.

like image 37
Muad'Dib Avatar answered Oct 10 '22 18:10

Muad'Dib


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.

like image 167
Kent Boogaart Avatar answered Oct 10 '22 18:10

Kent Boogaart