我在 WPF 应用程序中有一个附加属性。
下面的代码在 OnLoad
事件中,但除非我添加一个 500 毫秒的 hacky 延迟,否则它不起作用。
有什么方法可以避免这种延迟,并检测何时加载了可视化树?
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: In an attached property, how to wait until we are 100% sure that DevExpress has finished building its Visual Tree?
- DevExpress and How to ensure that a LayoutPanel is always in front of everything else?
更新 3
如果您在附加属性中,则可靠地加载可视化树的唯一方法是在 Loaded
事件处理程序中或之后执行代码。如果我们没有意识到这个限制,那么一切都会间歇性地失败。如上所述,一直等到 OnLoaded
事件触发后,远优于任何其他试图引入其他随机形式延迟的方法。
如果您使用的是 DevExpress,这就更重要了:在某些情况下,尝试在 Loaded
事件之前执行任何操作可能会导致崩溃。
例如:
- 在
Loaded
事件之前调用window.Show()
在某些情况下会导致崩溃。 - 在
Loaded
事件之前连接到IsVisibleChanged
的事件处理程序在某些情况下会导致崩溃。
免责声明:我与 DevExpress 无关,它是许多优秀的 WPF 库之一,我也推荐 Infragistics。
最佳答案
如果您想等待在 UI 线程中执行某些操作,请使用 Dispatcher .你怎么捕获它?那是个骗子。
How do I get the UI thread Dispatcher?
您可以使用 DispatcherPriority选择将来的时间。优先级基于 UI 事件,因此您不能说,例如,下周。但是您可以说“让我等到绑定(bind)处理完毕”,例如。
关于c# - WPF:在附加属性中,如何等待可视化树正确加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36037963/