簡體   English   中英

如何將 ResourceDictionary 樣式應用於代碼隱藏文件中的控件

[英]How to apply a ResourceDictionary style to a control in the code behind 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>

在我的文件后面的代碼中,我有一個標簽列表,其中包含一些 Label 控件。

private List<Label> labels;

有什么方法可以將 ResourceDisctionary 中的樣式應用於我的所有標簽? 到目前為止,我已經做到了這一點,但沒有應用樣式:

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

正如我在回答之前的評論中所說,如果最終目標是主題化,那么您的標簽是由程序自動生成還是在 xaml 中硬編碼都沒有關系。 您想要采取的方法是交換您的 ResourceDictionary 主題,看起來您正在嘗試這樣做,盡管我看到您只是添加而不是刪除。

此外,您不需要將每個標簽的樣式設置為鍵。 因為應用標簽的整體樣式取決於 ResourceDictionary。

這是一個例子:

Dictionary1.xaml:這是一個主題。 請注意,第二種樣式是將 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:這是另一個主題

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

主窗口.xaml

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

主窗口.xaml.cs

        private bool useSecondTheme;

        public MainWindow()
        {
            InitializeComponent();
        }

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

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:具體看 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));
        }
    }
}

每當我單擊“交換主題”按鈕時,它將在我定義的兩個 ResourceDictionaries 之間切換:

在此處輸入圖像描述

在此處輸入圖像描述

嘗試創建一個實際的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM