![](/img/trans.png)
[英]ObservableCollection in ViewModel is not updated when a List changes in Model
[英]Update UI when Entity Model changes in ViewModel
我试图想出一个使用Entity-Framework实现MVVM模式的好方法,其中我的实体是我的模型。 我的DataContext
是我的viewmodel。 这是一个小问题的再现。
视图
<TextBox Text="{Binding MyText}" />
ViewModel :
我需要从我的数据库中按记录导航记录。 在View中单击按钮时,会将命令发送到执行nextRecord()
的Viewmodel。 EF _myObject
其神奇作用, _myObject
是数据库中的下一行/记录
public class myViewModel: INotifyPropertyChanged
{
private MyEntityObject _myObject;
public string MyText
{
get { return _myObject.MyText; }
set
{
if (_myObject.MyText != value)
{
_myObject.MyText = value;
OnPropertyChanged("MyText");
}
}
}
private void _nextRecord()
{
_myObject = myEntitiesContext.NextRecord() //pseudocode
}
}
自动生成实体模型
public partial class MyEntityObject
{
public string MyText { get; set; }
}
由于View不知道_myObject
更改,因此_myObject
更改时不会更新。 我想到的一些方法。
我没有测试在INotifyPropertyChanged
包装类中包装我的实体,但我很谨慎,因为我有很多实体对象。
我可以为所有属性调用OnPropertyChanged("...")
,但是我的一些实体对它们有很多属性,这很难看。 可以使用反射使其更清晰,但我可能具有不是数据绑定的属性。
我可以将这个推迟到用户界面,当我点击“下一个记录”时,以某种方式刷新绑定,但这打破了MVVM并且看起来很脏
如何让UI识别_myObject
更改?
正如我在评论中提到的,调用OnPropertyChanged("")
或OnPropertyChanged(null)
会使所有属性无效,相当于为每个属性调用OnPropertyChanged
。 此行为也在此处记录 :
PropertyChanged事件可以通过使用null或String.Empty作为PropertyChangedEventArgs中的属性名称来指示对象上的所有属性都已更改。
这意味着您可以在更新对象时简单地添加对OnPropertyChanged("")
的调用,以强制WPF重新评估对视图模型的所有绑定:
private void _nextRecord()
{
_myObject = myEntitiesContext.NextRecord();
OnPropertyChanged("");
}
话虽这么说,我仍然会使用@Anand的解决方案(+1)。 关于viewmodel是否可以将模型公开为属性是一件正在进行的争论,我倾向于将它暴露出来,直到你需要引入一些特定于视图模型的逻辑。 大部分时间你都不需要,并且不值得包装模型属性。
您的代码的问题是,当_myObject
更改MyText
属性时,不会触发更改事件。 解决方法是创建一个新属性来保存实体,并在视图中将此属性作为Grid
的DataContext
,如下所示。 现在,当执行此行MyObject = myEntitiesObject.NextRecord()
您的视图将收到有关更改的通知。
public class myViewModel : INotifyPropertyChanged
{
private MyEntityObject _myObject;
public MyEntityObject MyObject
{
get { return _myObject; }
set {
if (_myObject != value)
{
_myObject = value;
OnPropertyChanged("MyObject");
}
}
}
private void _nextRecord()
{
MyObject = myEntitiesObject.NextRecord() //pseudocode
}
}
视图:
<Grid DataContext="{Binding MyObject}">
<TextBlock Text="{Binding MyText}"/>
</Grid>
一个非常简单但不是非常优雅的解决方案我认为可以满足需求:在切换记录时,将DataContext设置为null,然后再返回ViewModel。
然而,可以说更优雅的替代品需要更多的工作来满足所有要求。 请参阅Anand的答案以获得改进。
View中的标记应该具有设置值的mode和UpdateSourceTrigger属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.