如何在UI线程上的冗长任务期间强制UI更新

时间:2016-06-13 10:29:46

标签: wpf user-interface mvvm

我有一个窗口,窗口包含它的内容和“加载”叠加层,如下所示

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

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

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

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

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

然后,在程序处于“执行内容”部分期间,UI不会更新以显示加载覆盖。

如何解决此问题?

编辑:我找到了自己解决这个问题的方法。请参阅下面的答案。

1 个答案:

答案 0 :(得分:1)

通常在发生功能时,UI的任何更新都会被阻止,直到功能结束。这是因为直到函数结束才会推送框架。您可以通过调用这样的方法强制进行此更新;

    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函数中添加了一行,现在一切都按预期运行了!