Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a WPF style to a Border within a UserControl

I have a very simple UserControl, which just consists of a TextBlock contained within a Border element.

Is there a way of applying a style to the TextBlock within the UserControl from the containing window.

I know that I can create a style with..

<Style TargetType='TextBlock'>

But this applies to all TextBlocks within my window, not just the ones inside my UserControl

So I want to be able to say something like...

<Style TargetType='MyUserControl.TextBlock'>

Thanks,

Rich.

PS. this is a simplified example of what I'm trying to do!

ADDITIONAL NOTE

As I was driving home this evening, this was rattling around inside my head, and I thought of a possible solution.. and that's to create a basic sub-class of the TextBlock control, and call it MyTextBlock.. so just have a definition like

public class MyTextBlock : TextBlock { }

Then, within the usercontrol, use 'MyTextBlock' rather than 'TextBlock'. This will allow me to apply a style to a type of 'MyTextBlock'. Bingo !!!

Maybe this isn't the tidiest way of doing this, but it's very little code, and it works.

However, as I'm fairly new to WPF, I'm quite interested in a more standard way of acheiving this.

like image 822
Rich S Avatar asked Jan 17 '23 12:01

Rich S


1 Answers

One option if you want to apply a Style to all TextBlocks inside MyUserControl is this

<Style TargetType="{x:Type my:MyUserControl}">
    <Style.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Blue"/>
        </Style>
    </Style.Resources>
</Style>

And if you want to add another Style for MyUserControl you just have to base it on the default Style

<Style x:Key="myStyle" TargetType="{x:Type my:MyUserControl}"
       BasedOn="{StaticResource {x:Type my:MyUserControl}}">
    <!-- ... -->
</Style>

Otherwise, if you want to be able to set a Style for some controls inside MyUserControl you can use DependencyProperties. For a TextBlock you can have a style called TextBlockStyle for example. The TextBlock will bind to this Style and you can set the Style from your window (or wherever you use it). This can also be seen in some controls in the framework, AutoCompleteBox in the toolkit for example

<toolkit:AutoCompleteBox>
    <toolkit:AutoCompleteBox.TextBoxStyle>
        <Style TargetType="TextBox">
            <Setter Property="MaxLength" Value="10"/>
        </Style>
    </toolkit:AutoCompleteBox.TextBoxStyle>
</toolkit:AutoCompleteBox> 

MyUserControl.xaml

<Border BorderThickness="1">
    <TextBlock Style="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}},
                               Path=TextBlockStyle}"
               Text="Test"/>
</Border>

MyUserControl.xaml.cs

public partial class MyUserControl : UserControl
{
    public static DependencyProperty TextBlockStyleProperty =
        DependencyProperty.Register("TextBlockStyle",
                                    typeof(Style),
                                    typeof(MyUserControl));
    public MyUserControl()
    {
        InitializeComponent();
    }

    public Style TextBlockStyle
    {
        get { return (Style)GetValue(TextBlockStyleProperty); }
        set { SetValue(TextBlockStyleProperty, value); }
    }
}

And then you set the Style when you declare your instance in markup for example

<my:MyUserControl>
    <my:MyUserControl.TextBlockStyle>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Green"/>
        </Style>
    </my:MyUserControl.TextBlockStyle>
</my:MyUserControl>

Update

To set this on resource level you can add a default style for MyUserControl, in the window resources or App.xaml for example

<Window.Resources>
    <Style TargetType="{x:Type my:MyUserControl}">
        <Setter Property="TextBlockStyle">
            <Setter.Value>
                <Style TargetType="TextBlock">
                    <Setter Property="Foreground" Value="Green"/>
                </Style>
            </Setter.Value>                
        </Setter>
    </Style>
</Window.Resources>
like image 93
Fredrik Hedblad Avatar answered Jan 20 '23 02:01

Fredrik Hedblad