Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the styles at runtime in WPF

Tags:

c#

styles

wpf

I am trying to allow the user to customize the elements in a WPF application. What I am trying to achieve is, if I have a list box which specifies all the form elements (TextBox, label etc.) user can pick one form element, and set the style property say Label, foreground should be in orange where as for TextBox foreground should be in black and so on. And as per what ever style I am intending to apply all the TextBoxes should look alike.

I am not able to go figure out a way for achieving this. I have tried out an example where multiple pre-defined styles can be uploaded at runtime. So now, I would like to find a way of changing the property of different elements at runtime.

UPDATE:

I tried to create a new style from the code behind.

XAML

<Label Content="SAMPLE" Style="{DynamicResource Style1}" x:Name="label1" />
<Button Content="Button" Click="Button_Click" />

and in code behind i.e. on click of the Button I tried this:

Style style = new Style { TargetType = typeof(Label) };
style.Setters.Add(new Setter(Control.ForegroundProperty, Brushes.Black));
Application.Current.Resources["Style1"] = style;

But it is not getting updated.

Thanks.

like image 209
ds345 Avatar asked Aug 13 '13 04:08

ds345


People also ask

Is WPF still relevant 2021?

WPF is still one of the most used app frameworks in use on Windows (right behind WinForms).

Is WPF drag and drop?

Dragging-and-dropping between WPF applications and other Windows applications is also fully supported. In WPF, any UIElement or ContentElement can participate in drag-and-drop. The events and methods required for drag-and-drop operations are defined in the DragDrop class.


3 Answers

You have to make sure that the styles are in the file App.xaml:

<Application x:Class="ChangeStyleHelp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">

    <Application.Resources>
        <Style x:Key="MyStyle" TargetType="{x:Type Label}">
            <Setter Property="Background" Value="Green" />
        </Style>
    </Application.Resources>
</Application>

Code behind:

private void ChangeStyle_Click(object sender, RoutedEventArgs e)
{
    Style style = new Style 
    { 
        TargetType = typeof(Label) 
    };

    style.Setters.Add(new Setter(Label.BackgroundProperty, Brushes.Aquamarine));

    Application.Current.Resources["MyStyle"] = style;
}   

If the Style is in the resource of Window (Window.Resources), then you need to write this, or the name of the Window:

private void ChangeStyle_Click(object sender, RoutedEventArgs e)
{
    Style style = new Style 
    { 
        TargetType = typeof(Label) 
    };

    style.Setters.Add(new Setter(Label.BackgroundProperty, Brushes.Aquamarine));

    this.Resources["MyStyle"] = style;
}   

As well, you can change the Style this way: take an existing style and use of the element. Example:

<Application x:Class="ChangeStyleHelp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">

    <Application.Resources>
        <Style x:Key="AnotherWayStyle" TargetType="{x:Type Label}">
            <Setter Property="Background" Value="Lavender" />
            <Setter Property="Foreground" Value="OrangeRed" />
        </Style>
    </Application.Resources>
</Application>  

Code behind:

private void AnotherWay_Click(object sender, RoutedEventArgs e)
{
    label1.Style = (Style)Application.Current.Resources["AnotherWayStyle"];
}   
like image 181
Anatoliy Nikolaev Avatar answered Oct 08 '22 00:10

Anatoliy Nikolaev


Have you tried using Resource Dictionaries

Resource Dictionary

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="TextColor" Color="#FF121212"/>
</ResourceDictionary>

XAML for the control

<TextBox Text="TextBox" Foreground="{DynamicResource TextColor}" />

Code to change styles at runtime

     var rd = new ResourceDictionary();
     rd.Add("TextColor", "#FFFFFF");
     Application.Current.Resources.MergedDictionaries.Add(rd);

This will merge your new styles with the existing ones, and the change will be automatically reflected on all the controls linked with those styles.

like image 29
Sylens Avatar answered Oct 08 '22 01:10

Sylens


it worked for me like a charm:

Xaml:

<TreeView x:Name="TreePeople">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView> 

c#:

bool Expanded = false; 
// The event subscription method (for a button click)
private void ButtonExpand__Click(object sender, RoutedEventArgs e)
{
    Expanded = !Expanded;
    Style Style = new Style
    {
        TargetType = typeof(TreeViewItem)
    };

    Style.Setters.Add(new Setter(TreeViewItem.IsExpandedProperty, Expanded));
    TreePeople.ItemContainerStyle = Style;
}
like image 33
Darío Andrés Muñoz Prudant Avatar answered Oct 08 '22 00:10

Darío Andrés Muñoz Prudant