ViewModel的多个绑定更新

时间:2015-02-24 04:04:38

标签: c# wpf mvvm

我有一个MVVM模型

查看

<StatusBar>
<StatusBarItem>
<TextBlock Text="{Binding Status, UpdateSourceTrigger=PropertyChanged}" Width="Auto"/>
</StatusBarItem>
</StatusBar>

视图模型

ViewModel()
{
    public string Status { get; set; }

    void UpdateProcess()
    {
         UpdateStatus("Updating Database");
         Thread.Sleep(TimeSpan.FromSeconds(5));
         UpdateStatus("Database updated");
    }


    void UpdateStatus(string message)
    {
         Status = message;
         OnPropertyChanged("Status");
    }
}

当应用程序运行时,它仅在“正在更新数据库”之后显示“正在更新数据库”而不是“数据库更新”。 似乎只有在UpdateProcess方法运行

后才能更新视图

我需要在属性更改后立即更新视图。这可能吗?

即使我逐步调试代码,UI在通过第一个OnPropertyChanged时也不会更新。一旦整个UpdateProcess()完成,UI就会变为“”数据库更新“。

2 个答案:

答案 0 :(得分:1)

一旦内部值发生变化,您可以展开Status属性的setter以引发PropertyChanged

private string _status;
public string Status
{
  get
  {
    return _status;
  }
  set
  {
    _status = value;
    OnPropertyChanged("Status");
  }
}

当您设置Status属性时,PropertyChanged将触发并通知UI更新字段。

除了创建控件之外,这是WPF从绑定更新控件值的唯一方法。

可能产生影响的东西是绑定模式。

<StatusBar>
  <StatusBarItem>
    <TextBlock Text="{Binding Status, UpdateSourceTrigger=PropertyChanged}, Mode=TwoWay" Width="Auto"/>
  </StatusBarItem>
</StatusBar>

您可以查看here以查看更好的模式说明

答案 1 :(得分:1)

我认为问题在于您在长时间运行期间尝试显示状态消息,但它们没有显示出来。这很可能是因为您的长时间运行操作正在执行(并因此阻止)UI线程。当UI线程被阻止时,UI上的任何内容都不会更新;事实上,如果你长时间保持阻止,Windows会建议用户你的应用程序已经停止响应,应该关闭。

如果你使用的是带有async / await的C#版本,你可以这样做:

    private async Task UpdateProcess()
    {
        UpdateStatus("Updating Database");
        await Task.Run(UpdateDatabaseMethod);
        UpdateStatus("Database updated");
    }

    private void UpdateDatabaseMethod()
    {
        //Do long-running stuff in background...
        //Note that this will no longer be executing in the UI thread
        //so you may need to watch out for thread safety issues that you could previously ignore
        //This might mean adding some locks around your database access methods...
    }

对于异步/等待支持之前的版本,请查看BackgroundWorker

需要警惕的是,您现在正在后台线程中运行长时间运行的任务,这与阻止UI时的行为不同。这可能会带来许多新的挑战和麻烦,但不幸的是,如果您想要与长时间运行的任务并行运行UI,那么这是一个必要的恶魔。

其他问题包括用户现在可以在更新数据库时单击其他内容。如果您需要阻止UI交互,则需要一些其他机制来禁用在长时间运行操作时可能会干扰的控件。一种典型的方法是使用类似这样的状态消息的某种“忙碌指示器”对话框。