我在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;
});
}
});
}
按照@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);
}
如果使用DevExpress,则LayoutTreeHelper类可用于在可视树的上下扫描。
有关处理上下可视树的示例代码,请参见:
如果您处于附加属性中,则可靠地加载视觉树的唯一方法是在Loaded
事件处理程序中或之后执行代码。如果我们不了解此限制,那么一切都会间歇性地失败。OnLoaded
如上所述,等到事件触发后,它比尝试引入其他随机形式的延迟的方法要优越得多。
如果您使用的是DevExpress,这将变得更加关键:Loaded
在某些情况下,尝试在事件发生前做任何事情都可能导致崩溃。
例如:
window.Show()
,在Loaded
事件发生前调用会导致崩溃。IsVisibleChanged
在Loaded
事件发生之前将事件处理程序挂入钩子会导致崩溃。免责声明:我与DevExpress无关,它是许多不错的WPF库之一,我还建议使用Infragistics。
如果您想等待在UI线程中做某事,请使用Dispatcher。你如何抓住它?真是骗人
您可以使用DispatcherPriority选择将来的时间。优先级基于UI活动,因此例如下周就不能说了。但是,例如,您可以说“让我等到绑定处理完毕之后”。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句