如何在 UI 线程的冗长任务期间强制 UI 更新 [英] How to force a UI update during a lengthy task on the UI thread

查看:25
本文介绍了如何在 UI 线程的冗长任务期间强制 UI 更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个窗口,该窗口包含它的内容和一个加载"覆盖如下

I have a window, and the window contains it's content and a "Loading" overlay as follows

<Grid>
    <Grid>
        <!-- STUFF -->
    </Grid>
    <Rectangle Fill="White" Opacity="0.7" Visibility="{Binding VisibilityWait, Mode=TwoWay, 
    Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>

然后我的 ViewModel 实现 INotifyPropertyChanged 并包含属性;

My ViewModel then implements INotifyPropertyChanged and includes the property;

    private bool visibilityWait;
    public bool VisibilityWait
    {
        get
        {
            return visibilityWait;
        }
        set
        {
            visibilityWait = value;
            OnPropertyChanged("VisibilityWait");
        }
    }

我知道这是正确设置的,因为如果我在构造函数中将 VisibilityWait 设置为 true,则窗口会按预期显示正在加载"覆盖,反之亦然......但是,如果我尝试在方法例如;

I know that this is set up correctly because if I set the VisibilityWait to true in the constructor, the window displays with the "Loading" overlay as expected and vice versa... However, if i try to do this during a method e.g.;

private void someMethod()
{
    VisibilityWait = true;
    //... Do things
    VisibilityWait = false;
}

然后在程序处于执行操作"部分期间,UI 不会更新以显示加载叠加层.

Then during the time that the program is in the "do things" section, the UI does not update to show the loading overlay.

我该如何解决这个问题?

How do I solve this issue?

我找到了自己的解决方案.请参阅下面的答案.

I found my own solution to this problem. See the answer below.

推荐答案

通常当一个函数发生时,对 UI 的任何更新都会被阻止,直到函数结束.这是因为直到函数结束时帧才会被推送.您可以通过调用这样的方法来强制此更新;

Usually when a function is taking place, any updates to the UI are blocked until the end of the function. This is because the frame does not get pushed until the end of the function. You can force this update by calling a method like this;

    void AllowUIToUpdate()
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate (object parameter)
        {
            frame.Continue = false;
            return null;
        }), null);

        Dispatcher.PushFrame(frame);
        //EDIT:
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
                                      new Action(delegate { }));
    }

我在 AllowUIToUpdate 函数中添加了额外的一行,现在一切都按预期运行了!

I added in an extra line to the AllowUIToUpdate function, and now everything functions as expected!

这篇关于如何在 UI 线程的冗长任务期间强制 UI 更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆