Obecnie pracuję z szablonem Microsoft MVVM i frustruje mnie brak szczegółowych przykładów. Dołączony przykład ContactBook pokazuje bardzo mało obsługi poleceń, a jedyny inny przykład, jaki znalazłem, pochodzi z artykułu MSDN Magazine, w którym koncepcje są podobne, ale używa nieco innego podejścia i nadal nie jest skomplikowane. Czy są jakieś przyzwoite przykłady MVVM, które przynajmniej pokazują podstawowe operacje CRUD i przełączanie dialogów / treści?
Sugestie wszystkich były naprawdę przydatne i zacznę tworzyć listę dobrych zasobów
Struktury / szablony
Przydatne artykuły
- Aplikacje WPF ze wzorcem projektowym Model-View-ViewModel
- Walidacja danych w .NET 3.5
- Używanie ViewModel do dostarczania znaczących komunikatów o błędach walidacji
- Oparta na akcji walidacja modelu widoku i modelu
- Dialogi
- Powiązania poleceń w MVVM
- Więcej niż tylko MVC dla WPF
- Przykładowa aplikacja MVVM + Mediator
Screencasty
Dodatkowe biblioteki
- Ulepszona implementacja wzorca Mediator w WPF Disciples (bardzo polecam to dla aplikacji, które mają bardziej złożoną nawigację)
- Komunikator MVVM Light Toolkit
Odpowiedzi:
Niestety nie ma jednej świetnej przykładowej aplikacji MVVM, która robi wszystko, a istnieje wiele różnych podejść do robienia rzeczy. Po pierwsze, możesz chcieć zapoznać się z jednym z dostępnych frameworków aplikacji (Prism to przyzwoity wybór), ponieważ zapewniają one wygodne narzędzia, takie jak wstrzykiwanie zależności, polecenia, agregacja zdarzeń itp., Aby łatwo wypróbować różne wzorce, które Ci odpowiadają .
Wersja pryzmatu:
http://www.codeplex.com/CompositeWPF
Zawiera całkiem przyzwoitą przykładową aplikację (handlowca giełdowego) wraz z wieloma mniejszymi przykładami i instrukcjami. Przynajmniej jest to dobra demonstracja kilku popularnych wzorców podrzędnych, których ludzie używają, aby MVVM faktycznie działał. Sądzę, że mają przykłady zarówno dla CRUD, jak i dialogów.
Pryzmat niekoniecznie pasuje do każdego projektu, ale warto się z nim zapoznać.
CRUD: Ta część jest całkiem prosta, dwukierunkowe powiązania WPF ułatwiają edytowanie większości danych. Prawdziwą sztuczką jest zapewnienie modelu, który ułatwi konfigurację interfejsu użytkownika. Przynajmniej chcesz się upewnić, że Twój ViewModel (lub obiekt biznesowy) jest zaimplementowany
INotifyPropertyChanged
do obsługi powiązania i możesz powiązać właściwości bezpośrednio z kontrolkami interfejsu użytkownika, ale możesz również chcieć zaimplementować go wIDataErrorInfo
celu walidacji. Zazwyczaj, jeśli używasz jakiegoś rozwiązania ORM, konfiguracja CRUD jest bardzo prosta.W tym artykule przedstawiono proste operacje Crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
Jest on oparty na LinqToSql, ale nie ma to znaczenia dla przykładu - ważne jest tylko, aby zaimplementować obiekty biznesowe
INotifyPropertyChanged
(które klasy generowane przez LinqToSql robią). MVVM nie jest celem tego przykładu, ale nie sądzę, że ma to znaczenie w tym przypadku.W tym artykule przedstawiono sprawdzanie poprawności danych
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Ponownie, większość rozwiązań ORM generuje klasy, które już implementują
IDataErrorInfo
i zazwyczaj udostępniają mechanizm ułatwiający dodawanie niestandardowych reguł walidacji.W większości przypadków możesz wziąć obiekt (model) utworzony przez jakiś ORM i zawinąć go w ViewModel, który przechowuje go i polecenia do zapisywania / usuwania - i jesteś gotowy do powiązania interfejsu użytkownika bezpośrednio z właściwościami modelu.
Widok wyglądałby mniej więcej tak (ViewModel ma właściwość,
Item
która przechowuje model, jak klasa utworzona w ORM):Dialogi: Dialogi i MVVM są trochę trudne. Wolę używać podejścia Mediator w oknach dialogowych, możesz przeczytać więcej na ten temat w tym pytaniu StackOverflow:
przykład okna dialogowego WPF MVVM
Moje zwykłe podejście, które nie jest do końca klasycznym MVVM, można podsumować w następujący sposób:
Klasa bazowa dla okna dialogowego ViewModel, która udostępnia polecenia dla akcji zatwierdzenia i anulowania, zdarzenie, które informuje widok, że okno dialogowe jest gotowe do zamknięcia i cokolwiek innego będzie potrzebne we wszystkich oknach dialogowych.
Ogólny widok okna dialogowego - może to być okno lub niestandardowa kontrolka typu nakładki „modalnej”. W gruncie rzeczy jest to prezenter treści, do którego zrzucamy viewmodel i obsługuje okablowanie do zamykania okna - na przykład przy zmianie kontekstu danych można sprawdzić, czy nowy ViewModel jest dziedziczony z klasy bazowej, a jeśli tak, zasubskrybuj odpowiednie zdarzenie zamknięcia (program obsługi przypisze wynik dialogu). Jeśli zapewniasz alternatywną uniwersalną funkcjonalność zamykania (na przykład przycisk X), powinieneś upewnić się, że uruchomiłeś również odpowiednie polecenie zamknięcia w ViewModel.
Gdzieś, gdzie musisz dostarczyć szablony danych dla swoich ViewModels, mogą one być bardzo proste, zwłaszcza, że prawdopodobnie masz widok dla każdego okna dialogowego zamknięty w osobnej kontrolce. Domyślny szablon danych dla ViewModel wyglądałby wtedy mniej więcej tak:
Widok okna dialogowego musi mieć do nich dostęp, ponieważ w przeciwnym razie nie będzie wiedział, jak wyświetlić ViewModel, poza wspólnym interfejsem okna dialogowego jego zawartość jest zasadniczo taka:
Niejawny szablon danych zamapuje widok na model, ale kto go uruchamia?
To jest część niezbyt tak mvvm. Jednym ze sposobów jest użycie wydarzenia globalnego. Wydaje mi się, że lepiej jest użyć konfiguracji typu agregatora zdarzeń, dostarczanej przez wstrzykiwanie zależności - w ten sposób zdarzenie jest globalne dla kontenera, a nie dla całej aplikacji. Prism używa struktury Unity do semantyki kontenerów i wstrzykiwania zależności, i ogólnie bardzo lubię Unity.
Zwykle ma sens subskrybowanie tego zdarzenia przez okno główne - może otworzyć okno dialogowe i ustawić kontekst danych na ViewModel, który jest przekazywany z podniesionym zdarzeniem.
Skonfigurowanie tego w ten sposób pozwala ViewModels poprosić aplikację o otwarcie okna dialogowego i reagowanie na działania użytkownika w nim, nie wiedząc nic o interfejsie użytkownika, więc w większości MVVM-ność pozostaje kompletna.
Są jednak chwile, w których interfejs użytkownika musi podnieść okna dialogowe, co może nieco utrudnić sprawę. Zastanów się na przykład, czy pozycja okna dialogowego zależy od położenia przycisku, który je otwiera. W takim przypadku musisz mieć pewne informacje specyficzne dla interfejsu użytkownika, gdy żądasz otwarcia okna dialogowego. Generalnie tworzę oddzielną klasę, która zawiera ViewModel i kilka istotnych informacji o interfejsie użytkownika. Niestety, pewne sprzężenie wydaje się tam nieuniknione.
Pseudo kod programu obsługi przycisku, który wywołuje okno dialogowe wymagające danych pozycji elementu:
Widok okna dialogowego zostanie powiązany z danymi pozycji i przekaże zawarty ViewModel do pliku wewnętrznego
ContentControl
. Sam ViewModel nadal nie wie nic o interfejsie użytkownika.Ogólnie rzecz biorąc, nie używam
DialogResult
właściwości returnShowDialog()
metody ani nie oczekuję, że wątek będzie blokowany, dopóki okno dialogowe nie zostanie zamknięte. Niestandardowe modalne okno dialogowe nie zawsze działa w ten sposób, aw złożonym środowisku często nie chcesz, aby program obsługi zdarzeń i tak blokował w ten sposób. Wolę pozwolić ViewModels zająć się tym - twórca ViewModel może subskrybować odpowiednie zdarzenia, ustawiać metody zatwierdzania / anulowania itp., Więc nie ma potrzeby polegać na tym mechanizmie interfejsu użytkownika.Więc zamiast tego przepływu:
Używam:
Wolę to w ten sposób, ponieważ większość moich okien dialogowych to nieblokujące pseudo-modalne kontrolki i zrobienie tego w ten sposób wydaje się prostsze niż obejście tego. Łatwy do przeprowadzenia test jednostkowy.
źródło
Jason Dolinger wykonał dobry screencast z MVVM. Jak wspomniał Egor, nie ma jednego dobrego przykładu. Skończyły się. Większość z nich to dobre przykłady MVVM, ale nie dotyczy to złożonych problemów. Każdy ma swój własny sposób. Laurent Bugnion ma również dobry sposób komunikowania się między modelami widoków. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch jest również dobrym przykładem. Paul Stovel ma dobry post, który wyjaśnia również wiele z jego frameworku Magellana.
źródło
Czy spojrzałeś na Caliburna ? Próbka ContactManager zawiera wiele dobrych rzeczy. Ogólne przykłady WPF zapewniają również dobry przegląd poleceń. Dokumentacja jest dość dobra, a fora są aktywne. Zalecana!
źródło
Ten okazał się przydatny. Ma też kod.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
źródło
Tutaj dodaję link do aplikacji WPF (Inventory Management App), która używa zaprojektowanej przeze mnie architektury MVVM .
Jego interfejs użytkownika jest niesamowity. https://github.com/shivam01990/InventoryManagement
źródło
Przykładowy projekt w środowisku Cinch przedstawia podstawowe narzędzia CRUD i nawigacyjne. To dość dobry przykład wykorzystania MVVM i zawiera wieloczęściowy artykuł wyjaśniający jego użycie i motywacje.
źródło
Podzieliłem się też z twoją frustracją. Piszę aplikację i miałem te 3 wymagania:
Wszystko, co znalazłem, to kawałki i kawałki, więc zacząłem pisać to najlepiej, jak potrafiłem. Kiedy trochę się w to zagłębiłem, zdałem sobie sprawę, że mogą istnieć inne osoby (takie jak ty), które mogłyby korzystać z aplikacji referencyjnej, więc zrefaktorowałem ogólny materiał do frameworka aplikacji WPF / MVVM i wydałem go na licencji LGPL. Nazwałem go SoapBox Core . Jeśli przejdziesz do strony pobierania, zobaczysz, że jest dostarczana z małą aplikacją demonstracyjną, a kod źródłowy tej aplikacji demonstracyjnej jest również dostępny do pobrania. Mam nadzieję, że okaże się to pomocne. Jeśli chcesz uzyskać więcej informacji, napisz do mnie na adres scott {at} soapboxautomation.com.
EDYCJA : opublikował również artykuł w CodeProject wyjaśniający, jak to działa.
źródło
Napisałem prosty przykład MVVM od podstaw na projekcie kodu tutaj jest link MVVM WPF krok po kroku . Zaczyna się od prostej architektury 3-warstwowej i umożliwia korzystanie z niektórych struktur, takich jak PRISM.
źródło
Nawet ja podzielałem frustrację, dopóki nie wziąłem sprawy w swoje ręce. Zacząłem IncEditor.
IncEditor ( http://inceditor.codeplex.com ) to edytor, który próbuje wprowadzić programistów do WPF, MVVM i MEF. Uruchomiłem go i udało mi się uzyskać pewne funkcje, takie jak obsługa motywów. Nie jestem ekspertem od WPF, MVVM ani MEF, więc nie mogę włożyć w to wielu funkcji. Serdecznie proszę was, żebyście to ulepszyli, aby tacy wariaci jak ja mogli to lepiej zrozumieć.
źródło