WPF DataGrid:如何数据绑定SelectedItem的属性以触发INotifyPropertyChangedEvents?

时间:2010-10-07 18:12:41

标签: wpf data-binding mvvm datagrid inotifypropertychanged

我试图尽可能地做MVVM:
我的模型( InterestTypeEntity )实现了INotifyPropertyChanged 我的ViewModel( InterestTypeAllViewModel )有一个ObservableCollection,它绑定到DataGrid。当对其进行更改时,它会将这些更改(添加/删除)发送到数据库。

问题是,我希望能够在集合中对象的属性发生变化时更新数据库。我不知道该怎么办?到目前为止,这是我的代码......

XAML:

<DataGrid Name="TestGrid" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False"
          ItemsSource="{Binding IntTypes}" SelectedItem="{Binding CurrentIntType}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Interest ID" Binding="{Binding IntType}" />
        <DataGridTextColumn Header="Interested Parties Description" Binding="{Binding Description}" MaxWidth="500" />
    </DataGrid.Columns>
</DataGrid>

ViewModel代码:

public ObservableCollection<InterestTypeEntity> IntTypes 
{
    get { return DataRepository.InterestTypeEntities; }
}

public InterestTypeEntity CurrentIntType { get; set; }

public Int16 IntType
{
    get { return CurrentIntType.IntType; }
    set
    {
        if (value != CurrentIntType.IntType)
        {
            CurrentIntType.IntType = value;
            OnPropertyChanged("IntType");
        }
    }
}

public String Description
{
    get { return CurrentIntType.Description; }
    set
    {
        if (value != CurrentIntType.Description)
        {
            CurrentIntType.Description = value;
            OnPropertyChanged("Description");
        }
    }
}

3 个答案:

答案 0 :(得分:2)

不要创建模型对象的集合,也不要在(当前)视图模型上实现IntTypeDescription属性。除非您有其他理由这样做,否则请勿在模型中实现属性更改通知。

而是使IntTypes成为InterestTypeEntityViewModel个对象的集合。

此类包装InterestTypeEntity。它公开IntTypeDescription属性,a)包装基础InterestTypeEntity属性,b)执行属性更改通知。如果你使它的构造函数采用InterestTypeEntity参数,那么很容易在你的视图模型中填充:

IntTypes = new ObservableCollection<InterestTypeEntityViewModel>(
   DataRepository.InterestTypeEntities.Select(x => new InterestTypeEntityViewModel(x));

ItemsSource绑定到此集合。 (另外,将CurrentIntType设为InterestTypeEntityViewModel类型的属性,并在其发生变化时引发PropertyChanged。)

修改

如果属性在其集合中的项目发生更改时需要通知拥有的视图模型,则使其处理它们正在引发的PropertyChanged事件非常简单。在构造函数中,添加:

foreach (InterestTypeEntityViewModel vm in IntTypes)
{
  vm.PropertyChanged += InterestTypeEntityViewModel_PropertyChanged;
}

和这个方法:

private void InterestTypeEntityViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
   InterestTypeEntityViewModel vm = (InterestTypeEntityViewModel) sender;
   // check e.PropertyName and do whatever you need to do here.
}

如果从集合中删除对象,请不要忘记取消注册事件处理程序;否则,子视图模型对象将不会被处理,直到父视图对象。

顺便说一下,通过这种方式实现视图模型,您可以对基础实体模型的更新进行大量控制。例如,您可以在父视图模型中实现一个命令,该命令在单个操作中执行所有更新,另一个命令允许用户放弃他们在UI中所做的所有更改而不执行更新。所有这些逻辑都与实际的表示层完全分离。

答案 1 :(得分:1)

请参阅我的回答here。它将为您提供一个可观察的集合,告诉您集合何时更改,或集合中的项目发生更改。

答案 2 :(得分:0)

一般策略:

为绑定添加TwoWay:

SelectedItem="{Binding CurrentIntType,Mode=TwoWay}"

然后在ViewModel中订阅可观察集合的已更改事件。当集合发生变化时,将其发送到您的模型/ DAL并保留它。