wpf - INotifyPropertyChanged與ViewModel中的DependencyProperty




data-binding architecture mvvm dependency-properties (13)

選擇完全基於您的業務邏輯和UI抽象級別。 如果你不想要一個很好的分離,那麼DP將為你工作。

DependencyProperties主要適用於VisualElements級別,所以如果我們為每個業務需求創建大量的DP,將不是個好主意。 DP的成本比INotifyPropertyChanged還要高。 當您設計WPF / Silverlight時,嘗試設計完全獨立的UI和ViewModel,以便在任何時候我們都可以更改佈局和UI控件(基於主題和样式)

請參閱這篇文章 - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel 。 該鏈接有很多對Model-View-ViewModel模式的引用,這與此討論非常相關。

在Model-View-ViewModel體系結構WPF應用程序中實現ViewModel時,似乎有兩個主要選擇如何使其可用於數據綁定。 我已經看到使用DependencyProperty實現視圖將要綁定的屬性,而我已經看到實現INotifyPropertyChanged的ViewModel。

我的問題是我應該在什麼時候比另一個更喜歡? 是否有任何性能差異? 將ViewModel依賴關係提供給WPF真的是個好主意嗎? 做出設計決定時還需要考慮什麼?



為什麼喜歡DependencyObject只有一件事 - 綁定會更好。 只要嘗試一個ListBoxTextBox的例子,用INotifyPropertyChanged屬性與DependencyProperty數據填充列表並從TextBox編輯當前項目...


看起來應該在您創建的控件中使用依賴屬性,例如按鈕。 要在XAML中使用屬性並使用所有WPF功能,那些屬性必須具有依賴項屬性。

但是,您的ViewModel最好使用INotifyPropertyChanged。 如果需要,使用INotifyPropertyChanged將使您能夠獲得getter / setter邏輯。

我建議檢查一下已經實現INotifyPropertyChanged的ViewModel的Josh Smith版本的基類:

http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

我認為這是一個很好的如何做ViewModel的例子。


依賴屬性旨在支持在UI元素上綁定(作為目標),而不是作為數據綁定的源,這是INotifyProperty的出處。從純粹的角度來看,您不應該在ViewModels上使用DP。

“為了成為一個綁定的來源,屬性不需要是一個依賴屬性;你可以使用任何CLR屬性作為綁定源,但是為了成為綁定的目標,屬性必須是依賴項屬性為了使單向或雙向綁定有效,源屬性必須支持傳播到綁定係統和目標的更改通知。對於自定義CLR綁定源,這意味著該屬性必須支持INotifyPropertyChanged。集合應該支持INotifyCollectionChanged。“

所有依賴對像都不能被序列化(這可能妨礙ViewModel和DTO(POCO)的使用。

與WPF相比,Silverlight中的DP存在差異。

http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx

http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx


我最近也不得不考慮這個決定。

我發現INotifyPropertyChanged機制更適合我的需求,因為它允許我將GUI粘貼到現有的業務邏輯框架而不會重複狀態。 我使用的框架有自己的觀察者模式,很容易將一個級別的通知轉發到下一個。 我只是有一個類實現了我的業務邏輯框架和INotifyPropertyChanged接口的觀察者接口。

使用DP,您無法定義自己存儲狀態的後端。 我將不得不讓.net緩存我綁定到的每個狀態項的副本。 這看起來像一個不必要的開銷 - 我的狀態是龐大而復雜的。

所以在這裡,我發現INotifyPropertyChanged更適合將業務邏輯的屬性公開給GUI。

這就是說,我需要一個自定義的GUI小部件來公開一個屬性,並修改該屬性來影響其他GUI小部件。DP證明了這個簡單的解決方案。

所以我發現DP對GUI通知很有用。


我認為DependencyProperty和INotifyPropertyChanged用於Binding中的兩個不同的事情:第一個用於使屬性成為綁定的目標並從另一個屬性接收輸入(使用{Binding ...}來設置屬性),最後一個當您希望將某個屬性的值用作綁定源(綁定路徑表達式中的名稱)時。 所以選擇僅僅是技術性的。


我更喜歡更直接的方法,我在沒有INotifyPropertyChanged的Presentation Model中發表了博文。 使用數據綁定的替代方法,您可以直接綁定到CLR屬性,而無需任何簿記代碼。 您只需在視圖模型中編寫純舊的.NET代碼,並在數據模型更改時進行更新。


肯特寫了一個有趣的博客關於這個話題: 查看模型:POCOs與DependencyObjects

簡短的摘要:

  1. DependencyObjects未標記為可序列化
  2. DependencyObject類重寫並封裝Equals()和GetHashCode()方法
  3. 一個DependencyObject具有線程關聯 - 它只能在創建它的線程上訪問

我更喜歡POCO方法。 可以在此處找到實現INotifyPropertyChanged接口的PresentationModel(aka ViewModel)的基類: http : //compositeextensions.codeplex.com


將ViewModel依賴關係提供給WPF真的是個好主意嗎?

.NET 4.0將具有System.Xaml.dll,因此您不必依賴任意框架來使用它。 請參閱Rob Relyea關於他的PDC會話文章。

我的意思

XAML是一種描述對象的語言,WPF是一個描述對像是UI元素的框架。

它們的關係類似於C#,一種描述邏輯的語言,.NET,一種實現特定類型邏輯的框架。

XAML的目的是聲明式對像圖。 W * F技術非常適合這種範例,但XAML獨立存在。

XAML和整個依賴系統作為WF和WPF的獨立堆棧實現,可能會利用不同團隊的經驗,而不會在它們之間創建依賴關係(無雙關語意圖)。


依賴屬性是自定義控件創建的粘合劑。 如果您有興趣使用Intelli-sense在XAML設計時的屬性窗口中顯示屬性,則必須使用依賴屬性。 INPC絕不會在設計時在屬性窗口中顯示一個屬性。


如果你想將屬性公開給其他控件,你必須使用依賴屬性...但是祝你好運,因為他們需要一段時間才能弄清楚...


您可以使用此樣式觸發器:如果selecteditem為null,則選擇第一個元素。

<Trigger Property="SelectedItem" Value="{x:Null}">
    <Setter Property="SelectedIndex" Value="0"/>
</Trigger>




wpf data-binding architecture mvvm dependency-properties