简体   繁体   English

如何将 ResourceDictionary 样式应用于代码隐藏文件中的控件

[英]How to apply a ResourceDictionary style to a control in the code behind file

I have a ResourceDictionary as defined below in its own file:我在自己的文件中有一个如下定义的 ResourceDictionary:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WordSearch">

<Style x:Key="labelStyle">
        <Setter Property="Label.Foreground" Value="#8860D0"/>
    </Style>

</ResourceDictionary>

In my code behind file I have a list of labels containing some Label controls.在我的文件后面的代码中,我有一个标签列表,其中包含一些 Label 控件。

private List<Label> labels;

Is there any way I can apply the style from the ResourceDisctionary to all my labels?有什么方法可以将 ResourceDisctionary 中的样式应用于我的所有标签? So far I got as far as this but the style isn't applied:到目前为止,我已经做到了这一点,但没有应用样式:

ResourceDictionary skin = Application.LoadComponent(new Uri("BrightTheme.xaml", UriKind.Relative)) as ResourceDictionary;
            Resources.MergedDictionaries.Add(skin);

            for (int i = 0; i < labels.Count; i++)
            {
                labels[i].Style = (Style)skin["labelStyle"];
            }

As I stated in my comment before answering, if the ultimate goal is theming, then it doesn't matter if your labels are generated automatically by the program or hardcoded in xaml.正如我在回答之前的评论中所说,如果最终目标是主题化,那么您的标签是由程序自动生成还是在 xaml 中硬编码都没有关系。 The approach you want to take is to swap your ResourceDictionary theme, which it looks like you are trying to do, although I see you are only adding not removing.您想要采取的方法是交换您的 ResourceDictionary 主题,看起来您正在尝试这样做,尽管我看到您只是添加而不是删除。

Also, you don't need to set each Label's Style to a Key.此外,您不需要将每个标签的样式设置为键。 Because it is up to the ResourceDictionary to apply the Label's overall Style.因为应用标签的整体样式取决于 ResourceDictionary。

Here's an example:这是一个例子:

Dictionary1.xaml: This is one theme. Dictionary1.xaml:这是一个主题。 Notice the 2nd Style is the one that applies labelStyle to ALL of the labels请注意,第二种样式是将 labelStyle 应用于所有标签的样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="labelStyle" TargetType="Label">
        <Setter Property="Foreground" Value="#8860D0"/>
    </Style>
    <Style TargetType="{x:Type Label}" BasedOn="{StaticResource labelStyle}"/>
</ResourceDictionary>

Dictionary2.xaml: This is another theme Dictionary2.xaml:这是另一个主题

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ApplyLabelStyleOnUserControl">
    <Style x:Key="labelStyle" TargetType="Label">
        <Setter Property="Foreground" Value="DarkGreen"/>
    </Style>
    <Style TargetType="{x:Type Label}" BasedOn="{StaticResource labelStyle}"/>
</ResourceDictionary>

MainWindow.xaml主窗口.xaml

    <Grid>
        <StackPanel>
            <Button Content="Swap Theme" Click="Button_Click" Margin="15"/>
            <local:UserControl1 x:Name="userControl1" Margin="5"/>
        </StackPanel>
    </Grid

MainWindow.xaml.cs主窗口.xaml.cs

        private bool useSecondTheme;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            useSecondTheme = !useSecondTheme;
            userControl1.SwapTheme(useSecondTheme);
        }

UserControl1.xaml UserControl1.xaml

    <Grid>
        <StackPanel>
            <ListBox ItemsSource="{Binding MyLabels}">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListBoxItem">
                                    <Border>
                                        <Label Margin="5" Content="{Binding}"/>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>
            </ListBox>
            <Button Click="Button_Click" Content="Add Random Label" Margin="5"/>
        </StackPanel>
    </Grid>

UserControl1.xaml.cs: Look specifically at SwapTheme UserControl1.xaml.cs:具体看 SwapTheme

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace ApplyLabelStyleOnUserControl
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl, INotifyPropertyChanged
    {
        private ObservableCollection<string> myLabels;

        public ObservableCollection<string> MyLabels
        {
            get
            {
                if (this.myLabels == null)
                    this.myLabels = new ObservableCollection<string>();
                return this.myLabels;
            }
        }
        private static Random random = new Random();
        public string RandomString(int length)
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            return new string(Enumerable.Repeat(chars, length)
              .Select(s => s[random.Next(s.Length)]).ToArray());
        }

        public UserControl1()
        {
            InitializeComponent();
            this.DataContext = this;
            this.Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            // Initialize it with 5 random strings, but allow more labels to be added with a button on the UI.
            MyLabels.Add(RandomString(25));
            MyLabels.Add(RandomString(25));
            MyLabels.Add(RandomString(25));
            MyLabels.Add(RandomString(25));
            MyLabels.Add(RandomString(25));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Swaps between two themes
        /// </summary>
        /// <param name="useSecondTheme">when true it uses Dictionary2.xaml resource dictionary, otherwise it uses Dictionary1.xaml</param>
        internal void SwapTheme(bool useSecondTheme)
        {
            if (useSecondTheme)
            {
                // Remove the old theme
                ResourceDictionary oldSkin = Application.LoadComponent(new Uri("Dictionary1.xaml", UriKind.Relative)) as ResourceDictionary;
                Resources.MergedDictionaries.Remove(oldSkin);

                // Add the new theme
                ResourceDictionary newSkin = Application.LoadComponent(new Uri("Dictionary2.xaml", UriKind.Relative)) as ResourceDictionary;
                Resources.MergedDictionaries.Add(newSkin);
            }
            else
            {
                // Remove the old theme
                ResourceDictionary oldSkin = Application.LoadComponent(new Uri("Dictionary2.xaml", UriKind.Relative)) as ResourceDictionary;
                Resources.MergedDictionaries.Remove(oldSkin);

                // Add the new theme
                ResourceDictionary newSkin = Application.LoadComponent(new Uri("Dictionary1.xaml", UriKind.Relative)) as ResourceDictionary;
                Resources.MergedDictionaries.Add(newSkin);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyLabels.Add(RandomString(25));
        }
    }
}

Whenever I click the "Swap Theme" button, it will toggle between the two ResourceDictionaries that I defined:每当我单击“交换主题”按钮时,它将在我定义的两个 ResourceDictionaries 之间切换:

在此处输入图像描述

在此处输入图像描述

Try to create an actual ResourceDictionary and set its Source instead of calling Application.LoadComponent :尝试创建一个实际的ResourceDictionary并设置它的Source而不是调用Application.LoadComponent

ResourceDictionary skin = new ResourceDictionary() 
{ 
    Source = new Uri("BrightTheme.xaml", UriKind.Relative) 
};

for (int i = 0; i < labels.Count; i++)
{
    labels[i].Style = (Style) skin["labelStyle"];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在代码隐藏中将样式添加到ResourceDictionary - How to add a Style to a ResourceDictionary in code-behind 如何在后面的代码中将自定义样式应用于自定义控件 - How to apply a customized style to a custom control in code behind 如何从ResourceDictionary的代码隐藏访问UI控件 - How to access UI control from code-behind of ResourceDictionary 如何从代码隐藏文件中的合并ResourceDictionary获取资源? - How to get a resource from a merged ResourceDictionary in a code-behind file? 如何在另一个XAML文件中访问ResourceDictionary属性后面的代码? - How to access a code behind property of ResourceDictionary in another XAML file? WPF:如何访问后面的ResourceDictionary代码中的元素 - WPF: How to access element in ResourceDictionary code behind 我可以从(ResourceDictionary)后面的代码访问命名控件吗? - Can I get access from code behind (of a ResourceDictionary) to a named control? 如何在不使用ResourceDictionary Code-Behind的情况下处理来自ResourceDictionary的事件? - How to handle events from ResourceDictionary without using ResourceDictionary Code-Behind? 从代码更改样式(在ResourceDictionary中) - Change style (in ResourceDictionary) from code 在后面的代码中设置控件的StaticResource样式 - Set StaticResource style of a control in code behind
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM