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

发布于 2024-09-26 05:22:36 字数 1514 浏览 3 评论 0原文

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

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

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");
        }
    }
}

I'm trying to do this as MVVM as possible:
My Model (InterestTypeEntity) implements INotifyPropertyChanged.
My ViewModel (InterestTypeAllViewModel) has an ObservableCollection that binds to a DataGrid. When changes are made to it, it sends those changes (add/remove) to the Database.

the problem is, I want to also be able to update the database when the properties of the objects within the collection change. I'm not sure how to do that? Here's my code so far...

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 Code:

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");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兰花执着 2024-10-03 05:22:36

不要创建模型对象的集合,也不要在(当前)视图模型上实现 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 中所做的所有更改而不执行更新。所有这些逻辑都很好地与实际的表示层解耦。

Don't create a collection of model objects, and don't implement IntType and Description properties on your (current) view model. And unless you have some other reason to do so, don't implement property-change notification in your model.

Instead, make IntTypes a collection of InterestTypeEntityViewModel objects.

This class wraps InterestTypeEntity. It exposes IntType and Description properties that a) wrap the underlying InterestTypeEntity properties and b) performs property change notification. If you make its constructor take an InterestTypeEntity argument, it's easy to populate in your view model:

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

Bind the ItemsSource to this collection. (Also, make CurrentIntType a property of type InterestTypeEntityViewModel and raise PropertyChanged when it changes.)

Edit:

If the owning view model needs to be notified when properties change on the items in its collection, it's pretty simple to make it handle the PropertyChanged events they're raising. In your constructor, add:

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

and this method:

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

Don't forget to unregister the event handler if you remove an object from your collection; otherwise, the child view model objects won't get disposed until the parent one does.

Note, by the way, that by implementing the view models this way, you can exercise a lot of control over your updates to the underlying entity model. For instance, you can implement a command in your parent view model that does all of the updates in a single operation, and another one that lets the user discard all of the changes they've made in the UI without performing an update. And all of this logic is very nicely decoupled from the actual presentation layer.

梦在深巷 2024-10-03 05:22:36

此处查看我的回答。它将为您提供一个可观察的集合,告诉您集合何时发生变化,或者集合中的某个项目何时发生变化。

Please see my answer here. It will give you an observable collection that tells you when the collection changes, or when an item within the collection changes.

眸中客 2024-10-03 05:22:36

总体策略:

将 TwoWay 添加到您的绑定中:

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

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

General strategy:

Add TwoWay to your binding:

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

And then subscribe to the changed event of the observable collection in your ViewModel. When the collection changes, send it to your model/DAL and persist it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文