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.
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 TextBlock
s 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 TextBlock
s 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 Style
s 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.
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.