MVVM / ObservableCollection问题

时间:2011-02-25 22:43:59

标签: wpf silverlight mvvm

我有以下XAML:

   <Grid x:Name="LayoutRoot">
        <sdk:DataGrid AutoGenerateColumns="True" Margin="46,38,0,40" x:Name="FamilyListGrid" HorizontalAlignment="Left" Width="475" 
               ItemsSource="{Binding FamilyList}"
               SelectedItem="{Binding SelectedFamily, Mode=TwoWay}" />
    </Grid>

Binding中使用的我的FamilyList属性是我的视图模型类中的实体的ObservableCollection。我发现我需要在我的FamilyList集合的setter中实现INotifyPropertyChanged,否则绑定不起作用。我的理解是ObservableCollection已经实现了这一点。如果是这种情况,为什么我需要实现notify属性?

如果有帮助,这是我的FamilyList属性定义:

    private ObservableCollection<Services.Family> familyList;
    public ObservableCollection<Services.Family> FamilyList
    {
        get { return familyList; }
        private set 
        { 
            familyList = value;
            NotifyPropertyChanged("FamilyList");
        }
    }

6 个答案:

答案 0 :(得分:6)

ObservableCollection<T>实现INotifyCollectionChanged,它通知已注册的事件处理程序有关集合中的更改(添加,删除,排序项)。但是,DataGrid必须知道您的某个业务对象的属性是否已更改为更新网格中的值。为此,需要INotifyPropertyChanged ObservableCollection<T>也实现INotifyCollectionChanged。但是,如果集合的属性已更改,则只能用于通知。没有任何机制可以让集合检测您的业务对象是否已更改(如果它已经更改,它将注册到业务对象的INotifyCollectionChanged:)。

答案 1 :(得分:2)

ObservableCollection知道如果集合发生变化,即添加或删除项目,如何通知。

但是,如果您执行以下操作:

FamilyList = new ObservableCollection<FamilyList>(); 
// or
FamilyList = GetFamilyList();

然后您实际上正在更改包含您的集合的属性,这是不同的。我猜这是问题所在。

答案 2 :(得分:1)

ObservableCollection的INotifyPropertyChanged实现主要用于响应添加或删除该集合。

您需要在setter中调用Notify ...(),因为该集合是ViewModel的属性,并且DataGrid不会对ViewModel属性的任何更改做出反应,除非您调用Notify ...()时改变。

编辑: 我太慢了。

答案 3 :(得分:1)

只要在绑定列表/ DataContext设置之前创建了保存集合的属性,就应该没问题。如果更换集合,正如@Phil Sandler所说,您需要通知。如果创建时只在声明变量时执行new,或者在类的构造函数内部执行new,则不应该为 属性更改notify属性。如果您需要清除列表,我建议使用集合的Clear方法,而不是替换它。

答案 4 :(得分:0)

您正在更改可观察集合的实例,而不是可观察集合的内容。因此,该集合没有任何通知。

答案 5 :(得分:0)

如果集合本身添加或删除项目,则无需通知。但是,如果您将整个集合与新的/不同的实例(即familyList = new ObservableCollection<Services.Family>())交换,则需要通知。如果您确实在更改实例,请考虑清除/重新填充集合。