INotifyPropertyChanged vs. DependencyProperty in ViewModel

Podczas implementacji ViewModel w aplikacji WPF architektury Model-View - ViewModel wydaje się, że istnieją dwie główne opcje, jak uczynić ją możliwą do wykorzystania w bazie danych. Widziałem implementacje, które używają DependencyProperty dla właściwości, z którymi Widok będzie się wiązał i widziałem implementację ViewModel INotifyPropertyChanged zamiast tego.

Moje pytanie brzmi, Kiedy powinienem preferować jedno nad drugim? Czy są jakieś różnice w wydajności? Czy to naprawdę dobry pomysł, aby dać zależności ViewModel do WPF? Co jeszcze Muszę wziąć pod uwagę, kiedy podjąć decyzję projektową?

Author: lokusking, 2008-11-15

14 answers

Kent napisał ciekawy blog na ten temat: Zobacz modele: POCOs versus DependencyObjects .

Krótkie podsumowanie:

  1. DependencyObjects nie są oznaczone jako serializable
  2. Klasa DependencyObject nadpisuje i uszczelnia Equals () oraz Metody GetHashCode ()
  3. obiekt DependencyObject ma powinowactwo do wątków – można go uzyskać tylko na wątku, na którym była created

Wolę podejście POCO. Klasa podstawowa dla PresentationModel (aka ViewModel), który implementuje interfejs INotifyPropertyChanged można znaleźć tutaj: http://compositeextensions.codeplex.com

 205
Author: jbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 10:05:11

Zgodnie z przewodnikiem wydajności WPF, DependencyObjects zdecydowanie działają lepiej niż POCOs, które implementują INotifyPropertyChanged:

Http://msdn.microsoft.com/en-us/library/bb613546.aspx

 36
Author: James Ashley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-03 16:45:21

Wybór jest całkowicie oparty na logice biznesowej i poziomie abstrakcji interfejsu użytkownika. Jeśli nie chcesz dobrej separacji, DP będzie pracować dla Ciebie.

DependencyProperties będą stosowane głównie na poziomie VisualElements, więc nie będzie dobrym pomysłem, jeśli stworzymy wiele DPs dla każdego z naszych wymagań biznesowych. Istnieje również większy koszt dla DP niż INotifyPropertyChanged. Podczas projektowania WPF / Silverlight spróbuj zaprojektować interfejs użytkownika i ViewModel całkowicie oddzielnie, aby w dowolnym momencie możemy zmienić układ i sterowanie UI (na podstawie motywu i stylów)

Zobacz także ten post - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel. Link zawiera wiele odniesień do wzorca Model-View-ViewModel, co jest bardzo istotne w tej dyskusji.

 26
Author: Jobi Joy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:51

Z punktu widzenia ekspresji, bardzo lubię używać właściwości zależności i marudzę na myśl o INotifyPropertyChanged. Poza nazwami właściwości string i możliwymi wyciekami pamięci z powodu subskrypcji zdarzeń, INotifyPropertyChanged jest znacznie bardziej wyraźnym mechanizmem.

Właściwości zależności sugerują "kiedy to, zrób tamto" używając łatwo zrozumiałych metadanych statycznych. Jest to podejście deklaratywne, które dostaje mój głos na elegancję.

 19
Author: Bryan Watts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 23:41:22

INotifyPropertyChanged w przypadku użycia daje również możliwość dodania więcej logiki w kodzie getterów i settera swoich właściwości.

DependencyProperty przykład:

public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );

public String Name
{
    set { SetValue( NameProperty, value ); }
    get { return ( String ) GetValue( NameProperty ); }
}

W getterze i setterze - - - wszystko, co możesz zrobić, to po prostu wywołać odpowiednio SetValue i GetValue, b / c w innych częściach frameworka getter / setter nie jest wywoływany, zamiast tego bezpośrednio wywołuje SetValue, GetValue, więc twoja logika właściwości nie będzie niezawodnie wykonywana.

Za pomocą INotifyPropertyChanged zdefiniuj Zdarzenie:

public event PropertyChangedEventHandler PropertyChanged;

Oraz następnie wystarczy mieć dowolną logikę w dowolnym miejscu kodu, a następnie wywołać:

// ...
// Something cool...
// ...

if( this.PropertyChanged != null )
{
    PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}

// More cool stuff that will reliably happen...

To może być w getter/setter, lub gdziekolwiek indziej.

 16
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-25 13:38:53

Właściwości zależności są przeznaczone do obsługi wiązania (jako cel) elementów interfejsu użytkownika, a nie jako źródła do wiązania danych, w tym miejscu pojawia się INotifyProperty. Z czystego punktu widzenia nie powinieneś używać DP na modelach widoku.

" aby być źródłem wiązania, właściwość nie musi być właściwością zależności; możesz użyć dowolnej właściwości CLR jako źródła wiązania. Jednak, aby być celem wiązania, właściwość musi być właściwością zależności. Do jednokierunkowej lub dwukierunkowe Wiązanie aby było skuteczne, właściwość source musi obsługiwać powiadomienia o zmianach, które rozprzestrzeniają się do systemu wiązania, a tym samym do celu. Dla niestandardowych źródeł wiążących CLR oznacza to, że właściwość musi obsługiwać INotifyPropertyChanged. Kolekcje powinny wspierać INotifyCollectionChanged."

Wszystkie obiekty zależności nie mogą być serializowane (może to utrudnić korzystanie z ViewModels i Dto (POCO) ' s.

Istnieją różnice pomiędzy DP w Silverlight w porównaniu do WPF.

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

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

 16
Author: Nick Hermans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 10:07:49

Ja też musiałem ostatnio rozważyć tę decyzję.

Odkryłem, że mechanizm INotifyPropertyChanged lepiej odpowiadał moim potrzebom, ponieważ pozwolił mi przykleić mój GUI do istniejącego frameworka logiki biznesowej bez powielania stanu. Ramy, których używałem, miały własny wzór obserwatora i łatwo było przekazać jeden poziom powiadomień na następny. Po prostu miałem klasę, która zaimplementowała interfejs obserwatora z mojego frameworka logiki biznesowej i INotifyPropertyChanged interfejs.

Z DP nie możesz samodzielnie zdefiniować backendu, który przechowuje stan. Musiałbym pozwolić. NET buforować kopię każdego elementu stanu, z którym byłem związany. Wydawało się to zbędnym obciążeniem-Mój stan jest duży i skomplikowany.

Więc tutaj znalazłem INotifyPropertyChanged lepiej dla eksponowania właściwości z logiki biznesowej do GUI.

To powiedziane, gdy potrzebowałem niestandardowego widżetu GUI, aby odsłonić właściwość i aby zmiany w tej właściwości miały wpływ na inne Widgety GUI DP okazały się prostym rozwiązaniem.

Więc tam znalazłem DP przydatne dla GUI do GUI powiadomienia.

 7
Author: morechilli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-24 17:16:32

Czy to naprawdę dobry pomysł, aby dać zależności ViewModel do WPF?

. NET 4.0 będzie miał System.Xaml.dll, więc nie będziesz musiał brać zależności od dowolnego frameworka, aby go wykorzystać. Zobacz Roba Relyea ' s post o jego sesji PDC.

Moje ujęcie

XAML jest językiem do opisywania obiektów, a WPF jest frameworkiem, którego opisane obiekty są elementami interfejsu użytkownika.

Ich relacja jest podobna do C#, języka do opisywania logika, a. NET, framework implementujący poszczególne rodzaje logiki.

Celem XAML są deklaratywne wykresy obiektowe. Technologie W * F są świetnymi kandydatami do tego paradygmatu, ale XAML istnieje niezależnie od nich.

XAML i cały system zależności zostały zaimplementowane jako oddzielne stosy dla WF i WPF, prawdopodobnie w celu wykorzystania doświadczeń różnych zespołów bez tworzenia zależności (bez Kalambury) między nimi.

 6
Author: Bryan Watts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 09:25:07

Wydaje się, że właściwości zależności powinny być używane w formantach, które tworzysz, takich jak przyciski. Aby używać właściwości w XAML i używać wszystkich funkcji WPF, te właściwości muszą być właściwości zależności.

Jednak twój ViewModel jest lepiej używać INotifyPropertyChanged. Korzystanie z INotifyPropertyChanged daje możliwość getter / setter logiki, jeśli trzeba.

Polecam sprawdzenie wersji podstawowej klasy Josha Smitha dla Viewmodela, który już implementuje INotifyPropertyChanged:

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

Myślę, że jest to doskonały przykład jak zrobić ViewModel.

 4
Author: timothymcgrath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 01:59:11

Myślę, że DependencyProperty i INotifyPropertyChanged są używane do dwóch różnych rzeczy w wiązaniu : pierwszy dla umożliwienia właściwości być celem wiązania i otrzymać wejście z innej właściwości (use {Binding ...} aby ustawić właściwość), ostatnia, gdy chcesz, aby wartość właściwości była używana jako źródło powiązania (nazwa w wyrażeniu ścieżki powiązania). Wybór jest więc jedynie techniczny.

 4
Author: Domnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-02 18:37:07

Właściwości zależności są klejem tworzenia niestandardowej kontroli. Jeśli jesteś zainteresowany użyciem Intelli-sense do pokazania swoich właściwości w oknie Właściwości w czasie projektowania XAML, musisz użyć właściwości zależności. INPC nigdy nie wyświetli właściwości w oknie właściwości podczas projektowania.

 4
Author: John Peters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 21:04:28

Wolę bardziej bezpośrednie podejście, o którym pisałem na blogu w Modelu prezentacji bez INotifyPropertyChanged. Korzystając z alternatywy dla powiązania danych, można powiązać bezpośrednio z właściwościami CLR bez żadnego kodu księgowego. Wystarczy napisać zwykły stary kod. NET w modelu widoku, a zostanie on zaktualizowany, gdy zmieni się model danych.

 3
Author: Michael L Perry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-30 13:15:14

Jest tylko jedno, dlaczego warto wybrać DependencyObject - Wiązanie będzie działać lepiej. Po prostu wypróbuj przykład z ListBox i TextBox, uzupełnij listę danymi z właściwości INotifyPropertyChanged vs. DependencyProperty i edytuj bieżący element z TextBox...

 3
Author: ramos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-26 06:24:28

Jeśli chcesz udostępnić właściwości innym kontrolkom, musisz użyć właściwości zależności... Ale powodzenia, bo trochę im to zajmie...

 1
Author: JWP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-03 21:05:21