2010-07-07 53 views
0

從我認爲理解的是,在ModelView中實現INotifyPropertyChanged,允許在屬性被修改的情況下引發PropertyChanged事件。關於INotifyPropertyChanged和更新綁定的困惑

通過這種方式,視圖應該被通知基礎屬性已更改,因此UI應該獲取新的更改。

我理解正確嗎?

我面對的問題是我有一個Infragistics DataGrid綁定到ViewModel。只要我更改日期值,就可以看到ViewModel上的屬性如何正確設置並引發事件。但是我還沒有從外面訂閱這個事件,UI如何得到通知?

我在問這個,因爲我覺得用戶界面根本就不是。我已經放置第二個文本框,將您的ViewModel綁定到相同的基礎Model屬性。但是,如果我用DataGrid修改該屬性,TextBox(Mode = OneWay)不會自動更新。

我實際上使用MVVM-Light Frame工作,並使用ViewModelBase代替INotifyPropertyChanged並執行RaisePropertyChanged(...)。但結果應該是相似的。

我是否必須手動訂閱文本框到某個事件?

編輯:我已經解決了這個問題,但不明白爲什麼會發生這種情況。在回答問題之前,我需要更詳細地解釋一下這個架構。 Datogrid綁定到ViewModelA中的propertyA,返回ObservableCollection<ViewModelB>. ViewModelB實際上包含網格應顯示的所有屬性。所有這些屬性在Setters中自然會觸發OnProperyChanged。

TextBox綁定到PropertyB,它也存在於ViewModelA中。但它直接返回一個字符串,所以PerpertyB的基本的getter返回這樣的:如果我不綁定文本框這個propertyB,但其綁定到PropertyA以及然而

_cashflowInputs[0].ProjectedDate.ToString(); 

,它的工作原理:

它的奇怪。我期待它以同樣的方式工作。兩個屬性都生活在同一個ViewModel上並訪問相同的private ObservableCollection<ViewModelB>,它爲什麼要重要?

public ObservableCollection<ViewModelB> PropertyA 
     { 
      get { return _cashflowInputs;} 
     } 

     public string PropertyB 
     { 
      get { return _cashflowInputs[0].ProjectedDate.ToString(); } 
     } 

卡瓦

+0

只是爲了澄清,在你的代碼示例PropertyA是一個ObservableCollection和PropertyB是一個字符串?你說你將PropertyA(ObservableCollection)綁定到TextBox? – ChrisNel52 2010-07-07 15:24:32

+0

DataGrid綁定到PropertyA,TextBox綁定到PropertyB – Houman 2010-07-07 16:32:59

回答

2

這是數據對象實現INotifyPropertyChanged時數據對象和UI元素之間的通知如何工作的快速回顧。

1)調用數據對象上的屬性setter來更改屬性。

2)在setter中,數據對象更改屬性值並引發事件以通知綁定到數據對象的任何UI元素屬性已更改。所引發的事件將包含剛剛更改的屬性的名稱。

3)UI元素處理事件並檢查事件參數以確定哪個屬性發生了變化。

4)現在UI元素知道哪個屬性發生了變化,它調用相應的getter來獲取最新的屬性值,並使用該值更新自己。

所以,在你的例子中。如果屬性「ProjectedDate」已更新,則會引發一個事件,將屬性名稱「ProjectedDate」傳遞給UI元素。然後,UI元素將調用「ProjectedDate」屬性的getter以自行刷新。

如果從屬性名稱'PropertyB'作爲參數不會引發事件,UI元素不知道'PropertyB'發生了變化。因此,如果綁定到「PropertyB」,它將不會刷新自己的新值。在某些情況下,必須通過屬性名稱PropertyB提出一個事件作爲UI元素的事件爭論,以知道它需要使用最新的屬性值進行自我刷新。

+0

這完全可以解釋它。非常感謝您的澄清。現在我明白爲什麼人們不斷將它們稱爲魔術弦。 ;) – Houman 2010-07-08 07:51:03

0

你設置你的文本框綁定?

<TextBox Text="{Binding Path=PathToMyValue}"/> 
+0

是的,我做到了。 測試是我的ViewModel上的一個屬性。它正確顯示了初始值。但是當更新每個DataGrid的值時,我希望TextBox也得到更新。但它沒有。 – Houman 2010-07-07 14:02:01

+0

我會願意打賭,網格不做任何約束,它只是觀看集合添加/刪除項目。我們遇到了Infragistics數據網格BC的問題,它在數值改變時並沒有更新,我們需要近實時的數據更新。 – 2010-07-07 14:09:04

0

因爲控件的數據上下文將是ViewModelB,所以無法在DataGrid中的數據模板內的控件中綁定到PropertyB。如果要將數據模板內的元素綁定到數據模板上下文外的某個元素,則需要將其數據上下文設置爲其他值,或者使用元素到元素的數據綁定綁定到數據模板之外的某個元素。

+0

這兩個控件都在同一個StackGrid中,它的DataContext綁定到ViewModelA。另外我沒有使用任何DataTemplate。 ;)不用擔心,答案被找到。 – Houman 2010-07-08 07:52:40