views:

713

answers:

4

I have an external style resource in a resource dictionary I'm referencing with x:Key. It has an x:TargetType specifying a target (TextBlock). Is it possible to apply this to a control containing a TextBlock and have all TextBlock elements within that control have the style applied?

Thanks, Robert

A: 

No, but you can automatically apply a style to all elements of a certain type, like this:

<!-- Applies to all buttons in scope of this style -->
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
   ...
</Style>
Charlie
+3  A: 

The easiest way to do that would be to define a Style within the Control that is based on your external style resource, but don't specify an x:Key, just the TargetType.

<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource SomeOtherStyle}">

Without a key, it'll apply itself to all TextBlocks within the control.

Brandon
A: 

I think this is what you are looking for:

Your custom user control "test":

<UserControl x:Class="WpfApplication4.test"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Grid>
        <TextBlock>test</TextBlock>
    </Grid>
</UserControl>

Your Styles document "Res/Styles.xaml"

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
<Style TargetType="{x:Type TextBlock}">
    <Style.Setters>
        <Setter Property="Foreground" Value="Blue" />
    </Style.Setters>
</Style>

Your main window or parent:

<Window x:Class="WpfApplication4.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:WpfApplication4"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Res/Styles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <uc:test></uc:test>
</Grid>

The textblock in the custom control "test" now displays with a blue foreground.

Chris Persichetti
Yup; except this doesn't work in Silverlight. But that's cool; I solved it by wrapping the property in another. Thanks!
Robert Fraser
A: 

To expand a bit on other comments. When you use the syntax as Brandon showed:

<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource SomeOtherStyle}">

The BasedOn="" is basically a kind of "inheritance" of style. This style will have as its base set of setters the ones from the style it is based on. This gives you the ability to augment the style with the options that apply only in this case or, as your case requires, to redefine the scope of the style.

You have the style in your dictionary file as a keyed style, only able to be applied explicitly. By "re-defining" your style as Brandon showed you now can re-define the scope by leaving out the key, thus making it apply to all elements of the target type in the scope of that style. So if all your TextBlocks were in a Grid you could have something like this:

<Grid.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource MyBaseStyle}">     
</Style>
</Grid.Resources>
TheZenker