În punerea în aplicare a ViewModel în WPF arhitectura Model-View-ViewModel, se pare, există două opțiuni principale pentru modul de a face Bindable datelor. Am văzut implementări care folosesc DependencyProperty pentru proprietățile cu care este legat View, și am văzut că ViewModel de punere în aplicare INotifyPropertyChanged.
Întrebarea mea este când trebuie să dau preferință altui partener? Există diferențe în performanță? Este o idee bună să oferiți o dependență ViewModel pentru WPF? Ce altceva trebuie să iau în considerare atunci când iau o decizie de proiectare?
- DependencyObjects nu sunt marcate ca serializabile
- Clasa DependencyObject redefinește și compactează metodele Equals () și GetHashCode ()
- DependencyObject are o similitudine a firelor - accesul la acesta este posibil numai în firul pe care a fost creat
Conform Ghidului de performanță WPF, DependencyObjects funcționează cu siguranță mai bine decât POCOs care implementează INotifyPropertyChanged:
Alegerea se bazează în întregime pe logica dvs. de afaceri și pe nivelul de abstractizare al interfeței utilizator. Dacă nu doriți o bună separare, DP va lucra pentru dvs.
DependencyProperties se va aplica in principal la nivelul VisualElements, asa ca nu fi o idee bună, dacă vom crea mulțime de PD pentru fiecare dintre cerințele noastre de afaceri. De asemenea, pentru DP, un cost mai mare decât INotifyPropertyChanged. Când sunt în curs de dezvoltare un WPF / Silverlight, încercați pentru a personaliza pe deplin interfața și ViewModel, astfel încât, în orice moment putem schimba elementele de interfață de utilizator și de aspect (pe baza temelor și stiluri)
În termeni de expresivitate, îmi place foarte mult să utilizez proprietățile de dependență și să creez în gândul lui INotifyPropertyChanged. Pe lângă numele proprietăților de șir și posibilele scurgeri de memorie datorate abonării la evenimente, INotifyPropertyChanged este un mecanism mult mai explicit.
Proprietățile de dependență înseamnă "când este, fă-o", folosind metadate statice ușor de înțeles. Aceasta este o abordare declarativă, care îmi dă vocea pentru eleganță.
InotifyPropertyChanged când este folosit, de asemenea, vă oferă posibilitatea de a adăuga mai multă logică la codul getters și personalizatorul proprietăților dvs.
În getter și setter-ul --- tot ce poți face este pur și simplu apel SetValue și GetValue respectiv, b / c, în alte părți ale cadrului, care nu este numit getter / setter, în loc să-l apelează în mod direct SetValue, GetValue, deci logica proprietățile nu vor fi executate în mod fiabil.
Utilizați funcția INotifyPropertyChanged pentru a defini evenimentul:
Apoi folosiți orice logică în codul dvs., apoi apelați:
Acest lucru poate fi în cel care primește sau altundeva.
Proprietățile de dependență sunt proiectate să susțină legarea (ca un scop) la elementele interfeței utilizator, și nu ca o sursă de legare a datelor, aceasta este INotifyProperty. Din punct de vedere pur, nu trebuie să utilizați DP în ViewModels.
"Pentru a deveni o sursă obligatorie, o proprietate nu trebuie să fie o proprietate de dependență, puteți folosi orice proprietate CLR ca sursă obligatorie. Totuși, pentru a deveni un obiect obligatoriu, proprietatea trebuie să fie o proprietate dependentă. Pentru ca legătura unidirecțională sau bidirecțională să fie eficientă, proprietatea sursă trebuie să susțină notificarea modificărilor care se propagă în sistemul obligatoriu și, prin urmare, în țintă. Pentru sursele de legare CLR personalizate, aceasta înseamnă că proprietatea trebuie să susțină INotifyPropertyChanged. Colecțiile trebuie să sprijine INotifyCollectionChanged. "
Toate obiectele de dependență nu pot fi serializate (acest lucru poate interfera cu utilizarea ViewModels și DTO (POCO)).
Există diferențe între DP în Silverlight în comparație cu WPF.
De asemenea, am avut de luat în considerare această decizie recent.
Am constatat că mecanismul INotifyPropertyChanged potrivit pentru nevoile mele mai bună, deoarece mi-a permis să-mi lipici GUI la o structură existentă de logica de afaceri, fără a dubla de stat. Structura pe care am folosit-o avea propriul model de observator și era ușor să muți un nivel de notificare la următorul. Am avut o clasă care a implementat interfața de observator din logica mea de afaceri și interfața INotifyPropertyChanged.
Cu DP, nu puteți defini o backend care stochează starea în sine. Ar fi trebuit să .net cache o copie a fiecărui element de stat la care am fost atașat. Părea costuri generale inutile - starea mea este mare și complexă.
Deci, aici am găsit INotifyPropertyChanged mai bine pentru afișarea proprietăților din logica de afaceri din GUI.
Vorbind de unde am nevoie de o interfață grafică widget personalizat, pentru a expune o proprietate și pentru modificările aduse acestei proprietăți afecta alte widget-uri GUI, PD sa dovedit soluția simplă.
Deci, am găsit DP util pentru GUI să notifice GUI.
Este o idee bună să oferiți o dependență ViewModel pentru WPF?
NET 4.0 va avea System.Xaml.dll, deci nu trebuie să depindeți de o structură arbitrară care să o folosească. Vedeți mesajul lui Rob în sesiunea sa PDC.
XAML este o limbă pentru descrierea obiectelor și WPF este o structură ale cărei obiecte descrise sunt elementele interfeței de utilizator.
Relația lor este similară cu C #, limba descrierii logicii și .NET, o structură care implementează anumite tipuri de logică.
Scopul XAML este graficele declarative ale obiectelor. Tehnologiile W * F sunt candidați excelenți pentru această paradigmă, dar XAML există independent de ei.
XAML și întregul sistem dependențele au fost implementate ca stive separate pentru WF și un WPF, posibil să se utilizeze experiența de echipe diferite, fără a crea dependență (nici un joc de cuvinte destinate) între ele.
Se pare că proprietățile de dependență ar trebui să fie utilizate în controalele pe care le creați, cum ar fi butoanele. Pentru a folosi proprietățile în XAML și pentru a folosi toate funcțiile WPF, aceste proprietăți trebuie să aibă proprietăți de dependență.
Cu toate acestea, ViewModel-ul dvs. este mai bine să utilizați INotifyPropertyChanged. Utilizarea INotifyPropertyChanged vă va da posibilitatea de a avea logica getter / setter dacă aveți nevoie.
Vă recomandăm să verificați versiunea de bază a lui Josh Smith pentru ViewModel, care implementează deja INotifyPropertyChanged:
Cred că acesta este un exemplu excelent de a face ViewModel.
Mă gândesc la un DependencyProperty și INotifyPropertyChanged utilizate pentru două lucruri diferite în obligatorii: prima pentru a activa proprietățile atât o ancoră și primirea de intrare de la alte bunuri (utilizate pentru a seta proprietatea), acesta din urmă atunci când doriți valoarea proprietății a fost utilizată ca sursă de legare (nume în expresia expresiei de legare a expresiei). Astfel, alegerea este pur și simplu tehnică.
Proprietățile de dependență sunt adezivul pentru crearea unui control personalizat. Dacă sunteți interesat să utilizați Intelli-sense pentru a vă afișa proprietățile în fereastra de proprietăți în timpul dezvoltării XAML, trebuie să utilizați proprietățile Dependență. INPC nu va afișa niciodată o proprietate în fereastra de proprietăți în momentul proiectării.
Dacă doriți să expuneți proprietăți altor controale, trebuie să utilizați proprietățile Dependență. Dar noroc, pentru că au nevoie de timp pentru a înțelege.
Există un singur lucru, de ce trebuie să preferați DependencyObject - Legarea va funcționa mai bine. Doar încercați exemplul cu ListBox și TextBox. completați lista cu datele din proprietatea INotifyPropertyChanged și DependencyProperty și editați elementul curent din TextBox.