dus*_*ell 5 wpf elementhost winforms-interop
我在WinForms容器中托管WPF UserControl.现在,我希望能够主题/皮肤UserControl.为此,我有几个定义"皮肤"的资源字典.当我的应用程序启动时,我创建了一个"new System.Windows.Application()",以便Application.Current存在.要更改主题,将删除旧外观,并在运行时将新外观合并到应用程序级别资源字典中.但是,这不会更改UserControl中任何dyanamically引用的资源.我在一个直接的WPF应用程序中尝试了这个,它运行得很好.我错过了什么,或者根本不可能这样做?顺便说一句,如果我在UserControl初始化之前将一个皮肤添加到应用程序资源中,它将起作用,但之后我无法更改皮肤.
以最基本的方式回复这个:
创建一个新的WinForms应用程序.将WPF UserControl添加到应用程序.这很简单:
<UserControl ...>
<Grid>
<Button
Background="{DynamicResource ButtonBG}"/>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
使用具有相应颜色的键ButtonBG创建两个具有SolidColorBrush的ResourceDictionaries,White.xaml和Black.xaml(或其他).在Form1.cs中,添加两个按钮和一个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)));
}
Run Code Online (Sandbox Code Playgroud)
在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)));
...
}
Run Code Online (Sandbox Code Playgroud)
现在,当单击白色按钮时,我希望UserControl中的按钮变为白色,当单击黑色按钮时,我希望按钮变黑.但是,这不会发生.
有谁知道为什么?有解决方案吗?
编辑:想法:也许,如果有一种方法可以在主题发生变化时强制重新评估DynamicResources,那就行了.
谢谢,Dusty
我认为这可能是WPF框架中一个被忽视的问题.
从我通过Reflector可以看出,似乎当Application资源字典发生灾难性变化时(一种可能具有广泛影响的变化,如添加,删除或替换皮肤),有代码循环遍历所有Windows的申请并迫使他们重新评估他们的DynamicResources.但是,我认为WPF中顶级的其他元素ElementHost并没有得到同样的处理.这导致了我正在经历的行为.
我对这个问题的解决方法是手动遍历我ElementHost的所有s并添加,删除或替换皮肤ResourceDictionary文件.它并不完美,但它完成了工作.
| 归档时间: |
|
| 查看次数: |
2164 次 |
| 最近记录: |