Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override property of custom style

I have Style that applies to all of the buttons of my application:

<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="Background" Value="Red" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="FontSize" Value="16" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
                        <Ellipse.Width>
                            <Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
                        </Ellipse.Width>
                    </Ellipse>
                    <Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
                        <Ellipse.Width>
                            <Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
                        </Ellipse.Width>
                    </Ellipse>
                    <ContentPresenter HorizontalAlignment="Center"  
                                    VerticalAlignment="Center"/>
                </Grid>

                <ControlTemplate.Triggers>
                    ... some Triggers here
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

How can I change properties (e.g. FontWeight, FontSize etc.) in XAML? I tried this:

<Button FontWeight="Bold" FontSize="30" Foreground="Red">
</Button>

In the designer-view, I see the changes. But during runtime those changes are not applied.


After some investigation, I also have a Style for all TextBlock like this:

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="FontSize" Value="16" />
    <Setter Property="FontFamily" Value="Segoe UI Semibold" />
    <Setter Property="Foreground" Value="White" />
</Style>

This Style seems to override the TextBlock that is used on the Button. I still can't change the Text Properties in XAML.

Here's what it looks like if I use the Styles above in an empty project:

enter image description here

In the designer, the changes are applied, during runtime the one from the TextBlock are applied. If I assign a x:Key to the TextBlock, it works fine. But then I have to assign this Style to every TextBlock used in the app manually.

like image 736
el-nino Avatar asked Nov 24 '17 10:11

el-nino


2 Answers

You are facing typical style inheritance issue in wpf.

A control looks for its style at the point when it is being initalized. The way the controls look for their style is by moving upwards in logical tree and asking the logical parent if there is appropriate style for them stored in parent's resources dictionary.

In your case, you are using ContentPresenter in button as a default behaviour. and it is using TextBlock to represent text in button by default.

Therefore at the time of initialization, ContentPresenter finding TextBlock style and applying to represent content in button.

If you want to restrict ContentPresenter to look for the style then you have to bind a blank style to content presenter so that it will not look for any further style.

<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
            <Setter Property="Background" Value="Red" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="FontSize" Value="16" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
                                <Ellipse.Width>
                                    <Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
                                </Ellipse.Width>
                            </Ellipse>
                            <Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
                                <Ellipse.Width>
                                    <Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
                                </Ellipse.Width>
                            </Ellipse>
                            <ContentPresenter HorizontalAlignment="Center"  
                                    VerticalAlignment="Center">
                                <ContentPresenter.Resources>
                                    <Style TargetType="TextBlock" BasedOn="{x:Null}"/>
                                    <!--  Assigned Blank style here therefore it will not search for any further style-->
                                </ContentPresenter.Resources>
                            </ContentPresenter>
                        </Grid>


                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
like image 96
maulik kansara Avatar answered Oct 02 '22 17:10

maulik kansara


You can do it with the BasedOn. I show you an example.

<Window.Resources>
    <Style TargetType="ToggleButton" BasedOn="{StaticResource DefToggleButton}">
       <Setter Property="FontWeight" Value="Bold"/>
       <Setter Property="Content" Value="Some Cool Stuff"/>
           <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                      <Setter Property="Content" Value="More Stuff"/>
                </Trigger>
           </Style.Triggers>
    </Style>
</Window.Resources>

Here in my resources I have DefToggleButton, now in my xaml file I can set up any Property according to my need (which in this case is the FontWeight and Content Property).

like image 29
VegaBrothers Avatar answered Oct 02 '22 19:10

VegaBrothers