【问题标题】:Do I need to implement INotifyPropertyChanged when using EF Code-First?使用 EF Code-First 时是否需要实现 INotifyPropertyChanged?
【发布时间】:2011-10-22 21:55:27
【问题描述】:

我注意到,当使用 EF CodeFirst 并通过推荐的 DBSet.Local 属性将我的 UI 绑定到 ObservableCollection<T> here 时,UI 将在实体添加到 DBContext 时更新,但在实体添加时不会更新修改。

似乎没有通知DBSet.Local 集合我的实体已更改。使用 EF Code-First 时,我是否需要为我的所有字段实现 INotifyPropertyChanged?我在 Code-First 的任何示例中都没有看到这一点,这似乎与目的背道而驰,但也许我错了。

如果您认为ObservableCollection 应该接收更改通知并且我的实体类或其他某些东西一定有问题,我可以发布一些示例代码。

编辑所以,为了确定,如果我的 ViewModel 中有如下代码

private ClientContext clientContext;
private Client client;
public Client Client
{
    get { return client; }
    set { 
          client = value; 
          NotifyOfPropertyChange(() => Client);
          NotifyOfPropertyChange(() => Clients);
        }
}
public ObservableCollection<Client> Clients { get { return clientContext.Clients.Local; }}

我们还假设我的视图有一个 Listbox,其中 Itemssource 设置为 Clients,SelectedItem 设置为 Client。我仍然需要在我的模型中实现 INotifyPropertyChanged,即使我在我的 ViewModel 中使用它?

【问题讨论】:

  • 只有当 Client 对象本身在您的 ViewModel 中发生更改(对象引用的更改)时,您才会收到更改通知,但不会在例如客户端的 NameCity 更改时收到更改通知.为此,您必须在 Client 模型类的每个属性上实现更改通知。

标签: entity-framework mvvm ef-code-first observablecollection


【解决方案1】:

是的,

您希望在修改其属性时更新 UI 的每个元素都必须实现 INotifyPropertyChange。

这样做的原因是,UI 知道集合何时更改,但如果其中一个元素的属性发生更改,则没有与之关联的 CollectionChanged 事件,因此 UI 是无知的

另请参阅:Entity Framework CTP5 Code First, WPF - MVVM modeling

【讨论】:

  • 我已经编辑了我的问题,要求进一步澄清。您还会注意到,在您提供的最后评论的链接中提到使用 DBSet.Local 提供了一个 ObservableCollection,它本身实现了 INotifyPropertyChanged。
  • @meh:INotifyPropertyChangedObservableCollection 实现实际上并不关注集合子项的属性更改:social.msdn.microsoft.com/forums/en-US/wpf/thread/…
  • 我已经在我的模型类中实现了 INotifyPropertyChanged,似乎 EF Code First 应该自行处理。 /rant 多亏了你们两个,不知道 EF 在 Code-First 的底层做了什么有点令人困惑。
  • @meh,我知道它不在 EF 代码优先方法中,但您可能应该实现某种集合视图模型。这将实现一个ObservableCollection&lt;ClassViewModel&gt;,其中ClassViewModel 是一个封装模型的ViewModel。这样你就不需要用接口代码污染你的模型,你的 ViewModel 可以实现 INotifyPropertyChange
【解决方案2】:

这是一个不好的答案,但我将其包含在此处是为了有助于理解该问题。

答案似乎是“是”,您必须在模型中实现 INotifyPropertyChanged,以便控件收到更改通知(从而允许控件在更改时更新)。

但如果上述情况属实,为什么 TextBox 数据绑定到实体会导致其他控件发生变化。

试试吧!例如,您可以使用 UpdateSourceTrigger=PropertyChanged 将 TextBox 的 Text 属性绑定到 DataGrid 的 SelectedItem(从 .Local 绑定到 ObservableCollection)。现在运行并在 DataGrid 中选择一行并编辑 TextBox,DataGrid 行中的文本将实时更新!文本框如何强制 DataGrid 中的更改!?!?!

这是上例的绑定代码:

<TextBox Text="{Binding Path=SelectedItem.Name, UpdateSourceTrigger=PropertyChanged}" />

这不仅适用于同一视图上的文本框,而且即使实体是从 SelectedItem 收集并传递到第二个视图,该视图随后具有绑定到实体的文本框。 (设法实时更新第一个窗口的 DataGrid!)

这太酷了!现在我希望我能在代码中找到一种方法 SelectedItem.Name = "New Name",因为无论我尝试什么都不会更新 DataGrid。 (我无法直接刷新 DataGrid,因为我使用的是 MVVM 并且无权访问它)

注意:我将 EF4.1 与 DBContext 和 POCO 实体一起使用(即不实现任何接口的简单类)

【讨论】:

  • 将文本框绑定到数据网格中的 SelectedItem 是可行的,因为 SelectedItem 是一个依赖属性:msdn.microsoft.com/en-us/library/ms752914.aspx 依赖属性处理它们自己的自动更新,不需要实现 INotifyPropertyChange。它们是一种特定于 UI 的属性
猜你喜欢
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多