これについても同様の問題がありました。バックグラウンドをどのように実装しているのかわかりません。私は自分の状況を説明しようと試みることができます。独自のベース Window を作成しました。これを、Window から継承している MyWindow と呼びましょう。すなわち。
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}}"/>
初めては機能しますが、2回目には親のフリーズ可能なエラーが発生します。だから私の最初の考えは、ディスパッチャーを呼び出す必要があるだけのスレッドの問題だということでした。ウィンドウで呼び出す必要があると思ったので、ここで問題が発生しました。違います。そのリソースの依存オブジェクトでそれを呼び出す必要があります。
問題。リソースを探してそれへの参照を作成するため、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);
}
}
}
}
}
これで、background プロパティを設定するだけです。これはスタイルでも同じように機能するはずです。だからあなたはすることができます
this.SetValue(StyleProperty, temp)
それを理解するのに少し時間がかかりました。しかし、それが機能するようになると、私は爽快になりました。リソースが使用している依存オブジェクトでスレッドの問題が発生しているようです。最初は正しいスレッドですが、途中で別のスレッドが開始されます。まだこれを理解する必要があります。誰かがこれに対するより良い解決策を持っているなら、私はそれを見たいです.