正如我在回答之前的评论中所说,如果最终目标是主题化,那么您的标签是由程序自动生成还是在 xaml 中硬编码都没有关系。您想要采取的方法是交换您的 ResourceDictionary 主题,看起来您正在尝试这样做,尽管我看到您只是添加而不是删除。
另外,您不需要将每个标签的样式设置为键。因为要由 ResourceDictionary 来应用 Label 的整体样式。
这是一个例子:
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>
MainWindow.xaml
<Grid>
<StackPanel>
<Button Content="Swap Theme" Click="Button_Click" Margin="15"/>
<local:UserControl1 x:Name="userControl1" Margin="5"/>
</StackPanel>
</Grid
MainWindow.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 之间切换: