![](/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.