在WPF中在运行时更改样式

时间:2023-01-28 13:31:01

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.

我试图允许用户自定义WPF应用程序中的元素。我想要实现的是,如果我有一个列表框,指定所有表单元素(TextBox,标签等),用户可以选择一个表单元素,并设置样式属性说Label,前景应该是橙色的,其中至于TextBox前景应为黑色,依此类推。根据我打算应用的样式,所有TextBox都应该看起来很相似。

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

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.

谢谢。

3 个解决方案

#1


26  

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

您必须确保样式位于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:

如果Style位于Window(Window.Resources)的资源中,那么您需要编写它或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"];
}   

#2


4  

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

XAML用于控制

<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.

这会将您的新样式与现有样式合并,更改将自动反映在与这些样式链接的所有控件上。

#3


1  

it worked for me like a charm:

它对我有用,就像一个魅力:

Xaml:

XAML:

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

c#:

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;
}

#1


26  

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

您必须确保样式位于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:

如果Style位于Window(Window.Resources)的资源中,那么您需要编写它或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"];
}   

#2


4  

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

XAML用于控制

<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.

这会将您的新样式与现有样式合并,更改将自动反映在与这些样式链接的所有控件上。

#3


1  

it worked for me like a charm:

它对我有用,就像一个魅力:

Xaml:

XAML:

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

c#:

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;
}