Podczas implementowania ViewModel w aplikacji WPF o architekturze Model-View-ViewModel wydaje się, że istnieją dwie główne opcje, jak sprawić, by można było powiązać dane. Widziałem implementacje, które używają DependencyProperty
właściwości, z którymi View będzie wiązał się, i INotifyPropertyChanged
zamiast tego widziałem implementację ViewModel .
Moje pytanie brzmi, kiedy powinienem preferować jeden od drugiego? Czy są jakieś różnice w wydajności? Czy naprawdę dobrym pomysłem jest nadanie WPF zależności ViewModel? Co jeszcze muszę wziąć pod uwagę przy podejmowaniu decyzji projektowej?
INotifyPropertyChanged
.Odpowiedzi:
Kent napisał ciekawy blog na ten temat: Zobacz modele: POCO kontra DependencyObjects .
Krótkie podsumowanie:
Wolę podejście POCO. Klasę podstawową dla PresentationModel (aka ViewModel), która implementuje interfejs INotifyPropertyChanged, można znaleźć tutaj: http://compositeextensions.codeplex.com
źródło
Według przewodnika wydajności WPF, DependencyObjects zdecydowanie działają lepiej niż POCO, które implementują INotifyPropertyChanged:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
źródło
Wybór jest całkowicie oparty na logice biznesowej i poziomie abstrakcji interfejsu użytkownika. Jeśli nie chcesz dobrej separacji, DP będzie dla ciebie działać.
DependencyProperties będzie mieć zastosowanie głównie na poziomie VisualElements, więc nie będzie dobrym pomysłem, jeśli stworzymy wiele DP dla każdego z naszych wymagań biznesowych. Ponadto DP ma wyższy koszt niż INotifyPropertyChanged. Kiedy projektujesz WPF / Silverlight, spróbuj zaprojektować interfejs użytkownika i ViewModel całkowicie osobno, aby w dowolnym momencie mogliśmy zmienić układ i interfejs użytkownika (na podstawie motywu i stylów)
Zapoznaj się również z tym postem - /programming/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . Link ma wiele odniesień do wzorca Model-View-ViewModel, co jest bardzo istotne w tej dyskusji.
źródło
Z punktu widzenia ekspresji bardzo lubię używać właściwości zależności i kulić się na samą myśl
INotifyPropertyChanged
. Opróczstring
nazw właściwości i możliwych wycieków pamięci z powodu subskrypcji zdarzeń,INotifyPropertyChanged
mechanizm jest znacznie bardziej wyraźny.Właściwości zależności oznaczają „kiedy to zrób to”, używając łatwo zrozumiałych metadanych statycznych. To deklaratywne podejście zyskuje mój głos na elegancję.
źródło
[CallerMemberName]
.INotifyPropertyChanged
gdy jest używany, daje również możliwość dodania większej logiki w kodzie twoich metod pobierających i ustawiających właściwości.DependencyProperty
przykład:W swoim narzędziu pobierającym i ustawiającym --- wszystko, co możesz zrobić, to po prostu wywołać odpowiednio SetValue i GetValue, b / c w innych częściach struktury, w których getter / setter nie jest wywoływany, zamiast tego wywołuje bezpośrednio SetValue, GetValue, więc logika właściwości nie niezawodnie być wykonane.
Za pomocą
INotifyPropertyChanged
zdefiniuj zdarzenie:A potem po prostu umieść dowolną logikę w dowolnym miejscu kodu, a następnie wywołaj:
Może to być getter / setter lub gdziekolwiek indziej.
źródło
Właściwości zależności mają na celu wspieranie wiązania (jako celu) elementów interfejsu użytkownika, nie jako źródła powiązania danych, tutaj przychodzi INotifyProperty. Z czystego punktu widzenia nie należy używać DP w modelach ViewModels.
„Aby być źródłem powiązania, właściwość nie musi być właściwością zależności; można użyć dowolnej właściwości CLR jako źródła powiązania. Jednak aby być celem powiązania, właściwość musi być właściwość zależności. Aby wiązanie jedno- lub dwukierunkowe było skuteczne, właściwość źródłowa musi obsługiwać powiadomienia o zmianach propagowane do systemu powiązań, a tym samym do celu. W przypadku niestandardowych źródeł powiązania CLR oznacza to, że właściwość musi obsługiwać INotifyPropertyChanged. Kolekcje powinny obsługiwać INotifyCollectionChanged. ”
Nie można serializować wszystkich obiektów zależności (może to utrudnić korzystanie z ViewModels i DTO (POCO)).
Istnieją różnice między DP w Silverlight w porównaniu z WPF.
http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx
źródło
Ja też musiałem ostatnio rozważyć tę decyzję.
Odkryłem, że mechanizm INotifyPropertyChanged lepiej odpowiada moim potrzebom, ponieważ pozwolił mi przykleić GUI do istniejącej struktury logiki biznesowej bez powielania stanu. Framework, którego używałem, miał swój własny wzorzec obserwatora i łatwo było przekazać jeden poziom powiadomienia na następny. Po prostu miałem klasę, która zaimplementowała interfejs obserwatora z mojej struktury logiki biznesowej i interfejsu INotifyPropertyChanged.
W DP nie można zdefiniować backendu, który sam przechowuje stan. Musiałbym pozwolić .net buforować kopię każdego elementu stanu, który był dla mnie wiążący. Wydawało się to niepotrzebnym kosztem ogólnym - mój stan jest duży i skomplikowany.
Więc tutaj znalazłem INotifyPropertyChanged lepiej do eksponowania właściwości z logiki biznesowej na GUI.
Biorąc to pod uwagę, gdy potrzebowałem niestandardowego widżetu GUI do ujawnienia właściwości, a zmiany w tej właściwości wpływały na inne widżety GUI DP okazał się prostym rozwiązaniem.
Więc znalazłem DP przydatny do powiadomienia GUI do GUI.
źródło
.NET 4.0 będzie miał System.Xaml.dll, więc nie będziesz musiał polegać na dowolnej strukturze, aby z niego korzystać. Zobacz post Roba Relyea na temat jego sesji PDC.
Moje podanie
XAML to język opisujący obiekty, a WPF to framework, którego opisywane obiekty są elementami interfejsu użytkownika.
Ich związek jest podobny do C #, języka opisującego logikę, oraz .NET, frameworku, który implementuje określone 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 osobne stosy dla WF i WPF, prawdopodobnie w celu wykorzystania doświadczenia różnych zespołów bez tworzenia zależności między nimi (bez zamierzonej gry słów).
źródło
Właściwości zależności są klejnotem tworzenia niestandardowych elementów sterujących. Jeśli jesteś zainteresowany wykorzystaniem Intelli-sense do wyświetlania 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 pokaże właściwości w oknie właściwości w czasie projektowania.
źródło
Wygląda na to, że właściwości zależności powinny być używane w tworzonych kontrolkach, takich jak przyciski. Aby użyć właściwości w XAML i użyć wszystkich funkcji WPF, te właściwości muszą mieć właściwości zależności.
Lepiej jednak użyć ViewModel przy użyciu INotifyPropertyChanged. Korzystanie z INotifyPropertyChanged da ci możliwość posiadania logiki getter / setter, jeśli zajdzie taka potrzeba.
Polecam sprawdzenie wersji podstawowej klasy Josha Smitha dla modelu ViewModel, 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 tego, jak zrobić ViewModel.
źródło
Myślę, że DependencyProperty i INotifyPropertyChanged są używane do dwóch różnych rzeczy w Binding: po pierwsze, aby umożliwić właściwość jako cel wiązania i otrzymać dane wejściowe z innej właściwości (użyj {Binding ...}, aby ustawić właściwość), ostatni gdy chcesz, aby wartość właściwości była używana jako źródło wiązania (nazwa w wyrażeniu ścieżki wiązania). Zatem wybór jest wyłącznie techniczny.
źródło
Wolę bardziej bezpośrednie podejście, o którym pisałem w blogu w Modelu prezentacji bez INotifyPropertyChanged . Korzystając z alternatywy dla wiązania danych, można powiązać bezpośrednio z właściwościami CLR bez żadnego kodu księgowego. Po prostu piszesz zwykły kod .NET w swoim Modelu widoku i jest on aktualizowany, gdy zmienia się Twój model danych.
źródło
INotifyPropertyChanged
,PropertyDescriptor
co powoduje wycieki pamięciJest tylko jedna rzecz, dlaczego preferować
DependencyObject
- Wiązanie będzie działać lepiej. Po prostu spróbuj przykładu zListBox
iTextBox
, wypełnij listę danymi zINotifyPropertyChanged
właściwości vs.DependencyProperty
i edytuj bieżący element zTextBox
...źródło
Jeśli chcesz udostępnić właściwości innym kontrolkom, musisz użyć właściwości Zależności ... Powodzenia, ponieważ ich znalezienie zajmuje trochę czasu ...
źródło