MVVM viewmodel属性触发更新

MVVM viewmodel属性触发更新,mvvm,Mvvm,我开始为我的一个Silverlight应用程序实现MVVM。 (我没有使用任何工具箱) 我的页面包含一个带有两个组合框的部分。在其中一个组合中选择一个项目将触发更新组合下方可见网格的搜索 每个组合的选定项都绑定到我的视图模型中的属性。这些属性的设置程序将引发INotifyPropertyChanged属性更改,并自动更新绑定到网格的数据 一切都很好,直到我需要添加一个重置按钮,其目的是重置搜索参数,即:每个组合框不应指示任何项目,网格应为空 如果viewmodel中的重置函数更新了备份字段,U

我开始为我的一个Silverlight应用程序实现MVVM。 (我没有使用任何工具箱)

我的页面包含一个带有两个组合框的部分。在其中一个组合中选择一个项目将触发更新组合下方可见网格的搜索

每个组合的选定项都绑定到我的视图模型中的属性。这些属性的设置程序将引发INotifyPropertyChanged属性更改,并自动更新绑定到网格的数据

一切都很好,直到我需要添加一个重置按钮,其目的是重置搜索参数,即:每个组合框不应指示任何项目,网格应为空

  • 如果viewmodel中的重置函数更新了备份字段,UI将不会反映更改,因为不会调用RaisePropertyChanged
  • 如果viewmodel中的reset函数更新了属性,则UI将反映更改,但网格将更新两次:将第一个属性重置为null时,以及将第二个属性重置为null时
谢谢你的帮助

/// <summary>Selected user.</summary>
public User SelectedUser
{
    get { return _selectedUser; }
    set
    {
        _selectedUser = value;
        RaisePropertyChanged("SelectedUser");

        UpdateProducts();
    }
}

/// <summary>Selected product category.</summary>
public ProductCategory SelectedProductCategory
{
    get { return _selectedProductCategory; }
    set
    {
        _selectedProductCategory = value;
        RaisePropertyChanged("SelectedProductCategory");

        UpdateProducts();
    }
}

// Reset option 1
public void Reset()
{
    _selectedUser = null;
    _selectedProductCategory = null;
    _products = null;
}

// Reset option 2
public void Reset()
{
    SelectedUser = null;
    SelectedProductCategory = null;
    // No need to update Products which has already been updated twice...
}
///所选用户。
公共用户选择用户
{
获取{return\u selectedUser;}
设置
{
_selectedUser=值;
RaisePropertyChanged(“SelectedUser”);
UpdateProducts();
}
}
///所选产品类别。
公共产品类别已选择产品类别
{
获取{return\u selectedProductCategory;}
设置
{
_selectedProductCategory=值;
RaisePropertyChanged(“SelectedProductCategory”);
UpdateProducts();
}
}
//重置选项1
公共无效重置()
{
_selectedUser=null;
_selectedProductCategory=null;
_产品=空;
}
//重置选项2
公共无效重置()
{
SelectedUser=null;
SelectedProductCategory=null;
//无需更新已更新两次的产品。。。
}

如果使用支持字段,则必须调用

RaisePropertyChanged("SelectedUser");
RaisePropertyChanged("SelectedProductCategory");

在Reset()方法中。

在许多框架中,包括WPF,这确实让我感到不安。您需要的是延迟对更改通知的响应的一些概念,以便用户永远不会看到中间状态。但是,您无法更改WPF响应通知的方式,因此您最好将通知延迟到“尘埃落定后”。在您的情况下,您需要在发送任何通知之前更改这两个备份字段。您的重置方法可以将此想法编码如下:

public void Reset()
{
    _selectedUser = null;
    _selectedProductCategory = null;
    _products = null;

    RaisePropertyChanged("SelectedUser");
    RaisePropertyChanged("SelectedProductCategory");
}
在我看来,WPF同步更新显示以响应更改通知的方式是完全错误的。他们的DependencyProperty系统让他们有机会仅将依赖项标记为脏项,并在以后执行重新计算


我使用标记为脏的异步重新计算的思想作为您在这个问题中注意到的问题的一般解决方案,现在我无法想象没有它的编程。遗憾的是,更多的框架不能以这种方式工作。

在更新备份字段后,您可以为所有属性引发一个
PropertyChanged
事件:

RaisePropertyChanged(String.Empty);

谢谢你的回答,这正是我试图避免的:为同一个属性重复RaisePropertyChanged。我想理论上我不应该,但正如你所说,我可能没有选择……谢谢你的回答,我同意你的看法。这不仅在理论上是“错误的”,如果我碰巧更改了属性的名称,重构将无法更新关联的RaisePropertyChanged,如果它们位于一个位置(属性设置器),这也没关系但对我来说,它们在其他地方可用似乎很危险。请不要让我开始使用字符串进行属性更改通知。。。哦,那么脆弱和低效。你会认为微软定义核心API的人会更聪明一些。谢谢。这肯定会刷新所有控件,甚至那些与更改无关的控件。我的整个UI不是都会“闪烁”吗?是的,它会刷新绑定到viewmodel的所有内容。但我怀疑你能否看到它“眨眼”。。。