我有一个类似的问题。我不确定你是如何实现背景的。我可以试着解释一下我的情况,也许你能从中得到一些东西。我创建了自己的基础 Window,我们称它为 MyWindow,它继承自 Window。IE。
public class MyWindow : Window
{
}
我想要的是从应用程序资源字典中的动态资源应用背景。
我首先去了这个答案
public class MyWindow : Window
{
public MyWindow()
{
this.SetResourceReference(BackgroundProperty, "MyResourceKey");
}
}
现在,当资源是固定颜色时,这对我有用。
<SolidColorBrush x:Key="MyResourceKey" Color="White"/>
我发现当我将资源引用设置为系统颜色时,我会遇到您遇到的问题。
<SolidColorBrush x:Key="MyResourceKey" Color="{DynamicResource {x:Static SystemColors.WindowColorKey}}"/>
它会第一次工作,但第二次我会得到父可冻结错误。所以我最初的想法是,哦,这是一个线程问题,我只需要调用调度程序。现在这是我遇到障碍的地方,因为我认为我需要在窗口上调用它。不对。您需要在该资源的依赖对象上调用它。
问题。您没有使用 SetResourceReference 的对象,因为它会查找资源并创建对它的引用。所以我们需要的是实际的依赖对象。要从资源中获取对象,您可以执行此操作。
object temp = this.TryFindResource("MyResourceKey");
现在你有了对象,但这需要是一个依赖对象。我还没有尝试过,但你也许可以做到这一点
DependencyObject temp = (DependencyObjet)this.TryFindResource("MyResourceKey");
现在你有了依赖对象!这就是导致我们与可冻结父级的线程问题的原因。现在我们在这个对象上调用调度程序。我最终得到了这样的东西。这对我有用,但我可能会尝试清理一下。
public class MyWindow: Window
{
public MyWindow()
{
SetResources();
}
private void SetResources()
{
DependencyObject dependencyObject;
object temp;
temp = this.TryFindResource("MyResourceKey");
if (temp != null)
{
if (temp is DependencyObject)
{
dependencyObject = (DependencyObject)temp;
if (!dependencyObject.CheckAccess())
{
dependencyObject.Dispatcher.BeginInvoke(new System.Action(() => { this.SetResources(); }));
}
else
{
this.SetValue(BackgroundProperty, temp);
}
}
}
}
}
现在这只是设置背景属性。我相信这对于一种风格应该是一样的。所以你可以做
this.SetValue(StyleProperty, temp)
花了一点时间才弄清楚。但是一旦我得到它的工作,我就很兴奋。看起来我们的资源正在使用的依赖对象遇到了线程问题,因此它是第一次加载而不是第二次加载。第一次它在正确的线程上,但是在某个地方另一个线程被触发了。还想弄清楚这一点。如果有人对此有更好的解决方案,我很乐意看到它。