动态应用程序级资源在 ElementHost 中托管时不是动态的

2024-02-25

我在 WinForms 容器中托管 WPF UserControl。现在,我希望能够为 UserControl 设置主题/皮肤。为此,我有几个定义“皮肤”的资源字典。当我的应用程序启动时,我创建一个“new System.Windows.Application()”,以便 Application.Current 存在。要更改主题,旧皮肤将被删除,新皮肤将在运行时合并到应用程序级资源字典中。但是,这不会更改 UserControl 中任何动态引用的资源。我在一个直接的 WPF 应用程序中尝试过这个,它工作得很好。我是否错过了什么,或者根本不可能做到这一点?顺便说一句,如果我在 UserControl 初始化之前将皮肤添加到应用程序资源中,它将可以工作,但之后我无法更改皮肤。

以最基本的方式重新存储它:

创建一个新的 WinForms 应用程序。将 WPF 用户控件添加到应用程序。这很简单:

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

   ...
}

现在,当单击“白色”按钮时,我希望用户控件中的按钮变为白色,而当单击“黑色”按钮时,我希望该按钮变为黑色。然而,这并没有发生。

有谁知道为什么?有解决办法吗?

Edit:想法:也许,如果有一种方法可以在主题更改时强制重新评估 DynamicResources,那就行了。

谢谢, 尘土飞扬


我认为这可能是WPF框架中一个被忽视的问题。

据我通过 Reflector 得知,似乎当Application资源字典发生了灾难性的更改(这种更改可能会产生广泛的影响,例如添加、删除或替换皮肤),有一些代码循环遍历所有资源字典Windows并迫使他们重新评估自己的申请DynamicResources。然而,我会考虑的其他因素顶层在 WPF 中就像ElementHost却没有得到同样的待遇。这导致了我正在经历的行为。

我解决这个问题的方法是手动检查我的所有ElementHost单独添加、删除或更换皮肤ResourceDictionary文件。它并不完美,但它完成了工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态应用程序级资源在 ElementHost 中托管时不是动态的 的相关文章

随机推荐