我在 WinForms 容器中托管 WPF UserControl。现在,我希望能够为 UserControl 设置主题/皮肤。为此,我有几个定义“皮肤”的资源字典。当我的应用程序启动时,我创建了一个“新 System.Windows.Application()”,以便 Application.Current 存在。为了改变主题,旧皮肤被删除,新皮肤在运行时被合并到应用程序级资源字典中。但是,这不会更改 UserControl 中任何动态引用的资源。我在一个直接的 WPF 应用程序中尝试了这个,它工作得很好。我错过了什么,或者根本不可能做到这一点?顺便说一句,如果我在初始化 UserControl 之前将皮肤添加到应用程序资源中,它将起作用,但之后我无法更改皮肤。
以最基本的方式回购这个:
创建一个新的 WinForms 应用程序。将 WPF UserControl 添加到应用程序。这很简单:
<UserControl ...>
<Grid>
<Button
Background="{DynamicResource ButtonBG}"/>
</Grid>
</UserControl>
创建两个 ResourceDictionaries,White.xaml 和 Black.xaml(或其他),它们具有 SolidColorBrush,键为 ButtonBG,具有各自的颜色。在 Form1.cs 中,添加两个 Button 和一个 ElementHost。将 ElementHost 的子级设置为我们刚刚创建的 UserControl 的一个实例。将按钮连接到交换皮肤的事件:
private void White_Click(object sender, EventArgs e)
{
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));
}
private void Black_Click(object sender, EventArgs e)
{
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\Black.xaml", UriKind.Relative)));
}
在 Program.cs 中,确保 Application.Current 存在并设置初始皮肤:
[STAThread]
static void Main()
{
new System.Windows.Application();
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));
...
}
现在,当单击白色按钮时,我希望用户控件中的按钮变为白色,当单击黑色按钮时,我希望按钮变为黑色。然而,这不会发生。
有谁知道为什么?有解决办法吗?
编辑:想法:也许,如果有一种方法可以在主题更改时强制重新评估 DynamicResources,那将起作用。
谢谢,尘土飞扬