WPF アプリに添付プロパティがあります。
以下のコードはOnLoad
イベント内にありますが、ハッキーな 500 ミリ秒の遅延を追加しない限り機能しません。
この遅延を回避し、ビジュアル ツリーがいつ読み込まれたかを検出する方法はありますか?
private static void FrameworkElement_Loaded(object sender, RoutedEventArgs e)
{
// ... snip...
Window window = GetParentWindow(dependencyObject);
// Without this delay, changing properties does nothing.
Task task = Task.Run(
async () =>
{
{
// Without this delay, changing properties does nothing.
await Task.Delay(TimeSpan.FromMilliseconds(500));
Application.Current.Dispatcher.Invoke(
() =>
{
// Set False >> True to trigger the dependency property.
window.Topmost = false;
window.Topmost = true;
});
}
});
}
更新 1
@Willからの回答によると、「ディスパッチャーを使用して適切な優先度を選択してください」。これは見事に機能します:
private static void FrameworkElement_Loaded(object sender, RoutedEventArgs e)
{
// Wrap *everything* in a Dispatcher.Invoke with an appropriately
// low priority, to defer until the visual tree has finished updating.
Application.Current.Dispatcher.Invoke(
async () =>
{
// This puts us to the back of the dispatcher queue.
await Task.Yield();
// ... snip...
Window window = GetParentWindow(dependencyObject);
window.Topmost = true;
},
// Use an appropriately low priority to defer until
// visual tree updated.
DispatcherPriority.ApplicationIdle);
}
更新 2
DevExpress を使用している場合、LayoutTreeHelperクラスは、ビジュアル ツリーを上下にスキャンするのに役立ちます。
ビジュアル ツリーを上下にスキャンするサンプル コードについては、次を参照してください。
- DevExpress: 添付プロパティで、DevExpress がビジュアル ツリーの構築を完了したことを 100% 確信できるまで待つ方法は?
- DevExpress と LayoutPanel が常に他のすべての前にあることを確認する方法は?
アップデート 3
添付プロパティを使用している場合、ビジュアル ツリーを確実に読み込む唯一の方法は、イベント ハンドラー内またはLoaded
イベント ハンドラーの後でコードを実行することです。この制限を認識していないと、すべてが断続的に失敗します。上記のように、イベントが発生するまで待機するOnLoaded
ことは、他のランダムな形式の遅延を導入しようとする他の方法よりもはるかに優れています。
DevExpress を使用している場合、これはさらに重要です。Loaded
イベントの前に何かをしようとすると、状況によってはクラッシュする可能性があります。
例えば:
window.Show()
イベントの前に呼び出すLoaded
と、状況によってはクラッシュが発生しました。IsVisibleChanged
イベントが発生する前にイベント ハンドラーにフックすると、Loaded
状況によってはクラッシュが発生します。
免責事項: 私は DevExpress とは関係がありません。DevExpress は多くの優れた WPF ライブラリの 1 つです。Infragistics もお勧めします。