Search code examples
c#wpfstylessetter

Modify Properties inside a Style programmatically


I've got the following style defined in the resources of a UserControl:

<Style x:Key="MenuItemButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Width="40" Height="40" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="1,1,1,1" CornerRadius="3">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Button.Foreground" Value="#666666" />
    <Setter Property="Button.Background" Value="Transparent" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Button.Cursor" Value="Hand" />
            <Setter Property="Button.Foreground" Value="White" />
            <Setter Property="Button.Background" Value="#666666" />
        </Trigger>
    </Style.Triggers>
</Style>

For example I use it like the following:

<Button Click="Toolbar_DocumentMarkup_Click" Name="BtnUnderline" Margin="10,0,0,0" Style="{StaticResource MenuItemButton}">
    <fa:FontAwesome VerticalAlignment="Center" Icon="Underline" FontSize="24"/>
</Button>

I need to set the border's width and the height programmatically from the code behind so that the view will be updated on runtime.

What I tried so far:

Access the style through the Resources:

var style = Resources["MenuItemButton"] as Style

but I can't find the right properties in this style object.

Another idea:

Define the width and height as DependencyProperties or implement INotifyPropertyChanged, but I think in my case it's much easier to just set these two values programmatically.

Some oppinions or suggestions on this problem?


Solution

  • Add this to your resources:

     <sys:Double x:Key="ButtonHeight">200</sys:Double>
     <sys:Double x:Key="ButtonWidth">200</sys:Double>
    
    <Style x:Key="MenuItemButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Width="40" Height="40" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="1,1,1,1" CornerRadius="3">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Height" Value="{DynamicResource ButtonHeight}" />
    <Setter Property="Width" Value="{DynamicResource ButtonWidth}" />
    <Setter Property="Button.Foreground" Value="#666666" />
    <Setter Property="Button.Background" Value="Transparent" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Button.Cursor" Value="Hand" />
            <Setter Property="Button.Foreground" Value="White" />
            <Setter Property="Button.Background" Value="#666666" />
        </Trigger>
    </Style.Triggers>
    

    And then in your code behind you change it in your event using:

    this.Resources["ButtonHeight"] = ...
    

    and

    this.Resources["ButtonWidth"] = ...
    

    EDIT: forgot that of course you need to add the path to system

    xmlns:sys="clr-namespace:System;assembly=mscorlib"