Let's say I have two different, distinct stack panels (we'll call them SPA and SPB), each with 10 textblocks as child elements. All the textblocks in SPA should use one style, and all the textblocks in SPB should use another. One way to accomplish this would be to declare the two styles in Resources, and then append Style="style1"
to all 10 textblocks in the first stack panel, and append Style="style2"
to all 10 in the second one. However, it seems like there should be some easy way to append a style to the stackpanel itself that somehow tells the stackpanel to apply it to all child elements that are textblocks. Is there anyway to do this?
The reason I naturally look for this solution is because this is exactly how you do the same sort of thing in HTML with CSS, and I was hoping there would be a similar feature to XAML with styling.
Thanks!
P.S. I am working with Silverlight, but I'm guessing my situation and whatever solution (if there is one) applies to XAML/WPF in general.
In the resources section for your main container put your style with a x:Key
attribute and a target type of TextBlock
. Then in each resources section for each StackPanel
you can put a style where the BasedOn
attribute is set to the key of your main style (don't forget to use StaticResource binding, not just the name of the key) and then say TargetType="{x:Type TextBlock}"
and end the tag. this should bring the style into the StackPanel and style all of your TextBlocks.
<Window ...>
<Window.Resources>
<Style x:Key="tbstyle" TargetType="{x:Type TextBlock}">
<!-- put setters here -->
</Style>
</Window.Resources>
<StackPanel name="SPA">
<StackPanel.Resources>
<Style BasedOn="{StaticResource tbstyle}" TargetType="{x:Type TextBlock}" />
</StackPanel.Resources>
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
</Stackpanel>
<StackPanel name="SPB">
<StackPanel.Resources>
<Style BasedOn="{StaticResource tbstyle}" TargetType="{x:Type TextBlock}" />
</StackPanel.Resources>
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
<TextBlock ... />
</StackPanel>
</Window>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin"
Value="5" />
</Style>
</StackPanel.Resources>
<TextBlock Text="Text" />
<TextBlock Text="Text" />
<TextBlock Text="Text" />
<TextBlock Text="Text" />
</StackPanel>
You can accomplish this by overriding default text block style in the Resources of each stack panel:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background"
Value="Red"/>
</Style>
</StackPanel.Resources>
<TextBlock .../>
<TextBlock .../>
<TextBlock .../>
<TextBlock .../>
</StackPanel>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background"
Value="Green"/>
</Style>
</StackPanel.Resources>
<TextBlock .../>
<TextBlock .../>
<TextBlock .../>
<TextBlock .../>
</StackPanel>
I found one good solution for it here. Below is the sample code -
<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowWideStyleSample" Height="200" Width="300">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock>Header 1</TextBlock>
<TextBlock>Header 2</TextBlock>
<TextBlock Foreground="Blue">Header 3</TextBlock>
</StackPanel>
I hope this would help.