WPF MVVM刷新视图

时间:2016-11-02 21:46:55

标签: wpf mvvm

我有一个使用MVVM设计属性的WPF应用程序。有一个很长的运行过程来填充网格,我想显示一个忙碌的光标。我有部分改变光标工作。我遇到的问题是光标绑定到名为IsBusy的bool。当调用运行一段时间的方法时,我将IsBusy设置为true,当方法完成时,我将其设置为false。

public void LongProcedure(){ IsBusy=true; ... long running code here IsBusy=false; }`

我知道光标绑定到IsBusy是有效的,因为我用另一个执行

的过程测试了它
IsBusy=!IsBusy;

这会切换光标。我遇到的问题是,当方法中的代码运行时,视图似乎没有刷新。在我将IsBusy设置为true后,有没有办法强制视图重新设置?

1 个答案:

答案 0 :(得分:3)

在每个窗口化应用程序中,都有一个专门用于处理应用程序可视化表示的线程。这个帖子是the UI thread。当您的代码响应窗口事件(例如,Loaded事件或用户单击按钮)而运行时,它将在此UI线程上运行。当您的代码运行时,UI线程将占用执行您的工作,并且无法更新窗口的可视化表示。在极端情况下(即,您的工作需要花费大量时间才能完成),您的窗口将显示为已锁定。

如果您使用UI线程执行长时间运行的工作,那么您没有正确执行。您应该使用async-await,或使用Task.Run()以便在后台线程上执行

如果LongProcedure()是IO绑定的(比如从某处等待数据),那么你应该使用async-await。如果它受CPU限制(大量数据处理/计算),那么您应该使用Task.Run()

异步AWAIT:

public async Task LongProcedure()
{
    IsBusy = true;

    await GetDataFromSomewhereAsync();

    IsBusy = false;
}

public async void CallingMethod()
{
    ......
    await LongProcedure();
}

Task.Run:

public void LongProcedure()
{
    IsBusy = true;
    ... // long running code here
    IsBusy = false;
}
public async void CallingMethod()
{
    ......
    await Task.Run((Action) LongProcedure);
}

请注意,无法直接从后台线程更新UI。通常,您需要首先将更新代码编组到UI线程上。有许多不同的方法,它取决于您使用的Windows应用程序类型,例如windows formsWPF等。