private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Dispatcher.BeginInvoke(new Action(() => DoSomething()), DispatcherPriority.ContextIdle, null);
}
private void DoSomething()
{
//This will get called after the UI is complete rendering
}
public static class DispatcherExtensions
{
public static void DoEvents(this Dispatcher dispatcher, DispatcherPriority priority = DispatcherPriority.Background)
{
DispatcherFrame frame = new DispatcherFrame();
DispatcherOperation dispatcherOperation = dispatcher.BeginInvoke(priority, (Action<DispatcherFrame>)ExitFrame, frame);
Dispatcher.PushFrame(frame);
if (dispatcherOperation.Status != DispatcherOperationStatus.Completed)
dispatcherOperation.Abort();
}
private static void ExitFrame(DispatcherFrame frame)
{
frame.Continue = false;
}
public static void Flush(this Dispatcher dispatcher, DispatcherPriority priority)
{
dispatcher.Invoke(()=> { }, priority);
}
} 回想起来,我认为使用这个方法是一个糟糕的主意,因为它会导致很难解决的bug。
// this shows how bad it is to call Flush or DoEvents
int clicker = 0;
private void OnClick(object sender, RoutedEventArgs e)
{
if (clicker != 0)
{
// This is reachable... // Could be skipped for DispatcherPriority.Render but then again for render it seems to freeze sometimes.
}
clicker++;
Thread.Sleep(100);
this.Dispatcher.Flush(DispatcherPriority.Input);
//this.Dispatcher.DoEvents(DispatcherPriority.Render);
//this.Dispatcher.DoEvents(DispatcherPriority.Loaded);
//this.Dispatcher.DoEvents(DispatcherPriority.Input);
//this.Dispatcher.DoEvents(DispatcherPriority.Background);
clicker--;
}
3条答案
按热度按时间zlhcx6iw1#
在渲染开始时,调用
Dispatcher.BeginInvoke
,调度程序优先级为ContextIdle
。我的渲染开始只是碰巧是一个treeview选定项更改事件,但这可能是您需要等待UI完成更新的任何事件。
tvokkenx2#
是,使用Window.ContentRendered event。
jv4diomz3#
您可以覆写OnRender方法,以侦测呈现何时完成。
要推送所有事件,请调用Dispatcher.DoEvents(),其中DoEvents作为扩展方法实现:
}
回想起来,我认为使用这个方法是一个糟糕的主意,因为它会导致很难解决的bug。