在WPF中,是否有“渲染完成”事件?

e5njpo68  于 2022-11-18  发布在  其他
关注(0)|答案(3)|浏览(451)

在WPF中,当我载入含有许多元素的换行面板时, windows 会在显示内容之前停顿一段时间。我想要加入等待提示,但我找不到侦测换行面板何时完成呈现的方法。
我试过“加载”,“大小更改”,“初始化”都没有成功。有人对这个问题有什么想法吗?
非常感谢!

zlhcx6iw

zlhcx6iw1#

在渲染开始时,调用Dispatcher.BeginInvoke,调度程序优先级为ContextIdle
我的渲染开始只是碰巧是一个treeview选定项更改事件,但这可能是您需要等待UI完成更新的任何事件。

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
    }
tvokkenx

tvokkenx2#

是,使用Window.ContentRendered event

jv4diomz

jv4diomz3#

您可以覆写OnRender方法,以侦测呈现何时完成。
要推送所有事件,请调用Dispatcher.DoEvents(),其中DoEvents作为扩展方法实现:

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--;
}

相关问题