簡體   English   中英

在ViewModel中實體模型更改時更新UI

[英]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更改時不會更新。 我想到的一些方法。

  1. 我沒有測試在INotifyPropertyChanged包裝類中包裝我的實體,但我很謹慎,因為我有很多實體對象。

  2. 我可以為所有屬性調用OnPropertyChanged("...") ,但是我的一些實體對它們有很多屬性,這很難看。 可以使用反射使其更清晰,但我可能具有不是數據綁定的屬性。

  3. 我可以將這個推遲到用戶界面,當我點擊“下一個記錄”時,以某種方式刷新綁定,但這打破了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屬性時,不會觸發更改事件。 解決方法是創建一個新屬性來保存實體,並在視圖中將此屬性作為GridDataContext ,如下所示。 現在,當執行此行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM