简体   繁体   English

在ViewModel中实体模型更改时更新UI

[英]Update UI when Entity Model changes in ViewModel

I am trying to come up with a good way of implementing the MVVM pattern using Entity-Framework where my entities are my models. 我试图想出一个使用Entity-Framework实现MVVM模式的好方法,其中我的实体是我的模型。 My DataContext is my viewmodel. 我的DataContext是我的viewmodel。 This is a small reproduction of the problem. 这是一个小问题的再现。

View 视图

<TextBox Text="{Binding MyText}" />

ViewModel : ViewModel

I have the requirement of needing to navigate record by record from my DB. 我需要从我的数据库中按记录导航记录。 When a button is clicked in the View a command is sent to the Viewmodel that executes nextRecord() . 在View中单击按钮时,会将命令发送到执行nextRecord()的Viewmodel。 EF does its magic and _myObject is the next row/record from the database 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
    }
}

Autogenerated Entity Model 自动生成实体模型

public partial class MyEntityObject
{
     public string MyText { get; set; }
}

Since the View has no knowledge of _myObject changing, it doesn't update when _myObject changes. 由于View不知道_myObject更改,因此_myObject更改时不会更新。 A few approaches I have thought of. 我想到的一些方法。

  1. I haven't tested wrapping my entities in a INotifyPropertyChanged wrapper class but am wary to do this as I have a lot of entity objects. 我没有测试在INotifyPropertyChanged包装类中包装我的实体,但我很谨慎,因为我有很多实体对象。

  2. I could call OnPropertyChanged("...") for all properties, but some of my entities have a lot of properties to them, which would be ugly. 我可以为所有属性调用OnPropertyChanged("...") ,但是我的一些实体对它们有很多属性,这很难看。 Possible to use reflection to make it cleaner, but I may have properties that aren't databound. 可以使用反射使其更清晰,但我可能具有不是数据绑定的属性。

  3. I might be able to defer this to the UI, somehow refreshing the bindings when I click "Next Record", but this breaks MVVM and looks dirty 我可以将这个推迟到用户界面,当我点击“下一个记录”时,以某种方式刷新绑定,但这打破了MVVM并且看起来很脏

How can I get the UI to recognize changes from _myObject ? 如何让UI识别_myObject更改?

As I've mentioned in the comments, calling OnPropertyChanged("") or OnPropertyChanged(null) invalidates all properties and is equivalent to calling OnPropertyChanged for each and every property. 正如我在评论中提到的,调用OnPropertyChanged("")OnPropertyChanged(null)会使所有属性无效,相当于为每个属性调用OnPropertyChanged This behavior is also documented here : 此行为也在此处记录

The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs. PropertyChanged事件可以通过使用null或String.Empty作为PropertyChangedEventArgs中的属性名称来指示对象上的所有属性都已更改。

This means that you can simply add a call to OnPropertyChanged("") when you update your object to force WPF to reevaluate all bindings to your view model: 这意味着您可以在更新对象时简单地添加对OnPropertyChanged("")的调用,以强制WPF重新评估对视图模型的所有绑定:

private void _nextRecord()
{
    _myObject = myEntitiesContext.NextRecord();
    OnPropertyChanged("");
}

That being said, I'd still go with @Anand's solution (+1). 话虽这么说,我仍然会使用@Anand的解决方案(+1)。 There's an ongoing debate on whether it's OK or not for the viewmodel to expose the model as a property, and I tend to go with exposing it until you need to introduce some view model specific logic. 关于viewmodel是否可以将模型公开为属性是一件正在进行的争论,我倾向于将它暴露出来,直到你需要引入一些特定于视图模型的逻辑。 Most of the time you won't have to and it's not worth the trouble of wrapping model properties. 大部分时间你都不需要,并且不值得包装模型属性。

The problem with your code is that when _myObject changes the MyText property changed event is not fired. 您的代码的问题是,当_myObject更改MyText属性时,不会触发更改事件。 A work around would be to create a new property to hold you entity and make this property as your Grid s DataContext in your view as shown below. 解决方法是创建一个新属性来保存实体,并在视图中将此属性作为GridDataContext ,如下所示。 Now when this line is executed MyObject = myEntitiesObject.NextRecord() your view will be notified about the change. 现在,当执行此行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
    }
}

View: 视图:

    <Grid DataContext="{Binding MyObject}"> 
        <TextBlock Text="{Binding MyText}"/>
    </Grid>

An extremely simple but not very elegant solution that I believe would meet needs: upon switching records, set the DataContext to null, then back to the ViewModel. 一个非常简单但不是非常优雅的解决方案我认为可以满足需求:在切换记录时,将DataContext设置为null,然后再返回ViewModel。

However, there are arguably more elegant alternatives that require more work to meet all requirements. 然而,可以说更优雅的替代品需要更多的工作来满足所有要求。 See Anand's answer for an improvement upon this. 请参阅Anand的答案以获得改进。

View中的标记应该具有设置值的mode和UpdateSourceTrigger属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当Model中的List发生更改时,ViewModel中的ObservableCollection不会更新 - ObservableCollection in ViewModel is not updated when a List changes in Model 实体框架更新模型以反映数据库中的更改 - Entity Framework to update the Model to reflect the changes in database 模型更改后更新数据库 - 实体框架7 - Update Database after Model Changes - Entity Framework 7 ViewModel和Model并观察更改 - ViewModel and Model and observing changes 更新列表<model>如果 UI 有任何变化,项目</model> - Update List<model> items if there are any changes in UI 在实体修改中注册ViewModel中的更改 - Register changes in the ViewModel on Entity modifications 数据库位置更改时如何更新.edmx文件(实体数据模型工具) - How to update an .edmx File when the Database Location Changes (Entity Data Model Tools) 在基础模型数据更改时,通知ViewModel中定义的属性更改 - Notify property change defined in the ViewModel when underlying Model data changes 当模型更改时,MVVM更新视图模型 - MVVM update view model when model changes 将数据库模型从实体映射到视图模型时,Automapper缺少类型 - Automapper missing type when mapping database model from entity to viewmodel
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM