View Switching - MVVM - Best Practice

  • WPF

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    View Switching - MVVM - Best Practice

    Hallo,
    da ich meist Anwendunge habe, die aus mehreren Anwendungsseiten und darunter mehreren HauptContent Seiten besteht, habe ich versucht, das switchen zwischen den Views in MVVM umzusetzen, ohne Verwendung von Messenger, Services oder Dependency Injection.
    Im Anhang habe ich ein Beispielprojekt.
    Das Projekt besteht aus mehreren Hauptseiten (ApplicationContent) und aus mehreren Unterseiten der MainPage (MainPage Content).
    Es gibt nur 1 Fenster und alle "Seiten" sollen innerhalb dieses Fensters geschaltet werden.
    Dazu habe ich in der App.xaml für jede Seite und jede Unterseite ein Datatemplate erstellt.
    Es gibt ein HauptViewmodel (ApplicationViewModel) welches sich um die Anwendung selbst kümmert.
    Darin gibt es ein Property vom Typ IApplicationContent CurrentApplicationContent welches dann im MainWindow an einen ContentPresenter gebunden ist.
    Der Aufbau der Anwendung ist wie folgt:
    es gibt 3 Hauptseiten die im ContentPresenter angezeigt werden können, LoginControl, RegisterControl und MainControl.
    Das MainControl wiederum ist der HauptContent für die Unterseiten, deswegen habe ich in dem dazugehörigen MainPageViewModel wieder ein Property, disemal vom Typ IMainPageContent erstellt und an einen ContentPresenter gebunden.
    Darüberhinaus hat die MainPage ein Seitenmenü welches an ein Property vom Typ SideMenuViewModel gebunden ist.
    Das Seitenmenü dient dann zum schalten der Unterseiten der MainPage.

    Beide ViewModels (ApplicationViewModel und MainPageViewModel) haben zusätzlich eine Methode um das ViewModel zu ändern.

    C#-Quellcode

    1. public void ChangeApplicationContent(IApplicationContent vm)
    2. {
    3. CurrentApplicationContent = vm;
    4. }
    5. public void ChangeMainPageContent(IMainPageContent vm)
    6. {
    7. CurrentMainPageContent = vm;
    8. }


    Das MainControl kann dann mehrere Unterseiten anzeigen (PersonListControl, PersonDetailControl, CompanyListControl, CompanyDetailControl und SettingsControl).
    Das PersonDetailControl und das CompanyDetailControl werden vom PersonListControl bzw. vom CompanyListControl angesteuert.

    Um nun zu schalten habe ich jeweils in den jeweiligen ViewModels ein Private Field vom Typ ApplicationViewModel bz. MainPageViewModel erstellt und im Falle des SideMenuViewModel sogar von beiden.

    Im entsprechenden Command kann ich dann über _appViewModel.ChangeApplicationContent(new RegisterViewModel(_appViewModel)) bzw. _mainPageVm.ChangeMainPageContent(new PersonListViewModel(_mainPageVm))
    das entsprechende ViewModel erstellen und die WPF sucht das dazu passende Control raus.

    Das funktioniert einwandfrei.

    Die Frage hier ist nur, ist das Best Practice? Oder wie setzt man dieses Szenario anständig um? Denn ich reiche ja ständig eine neue Instanz der ApplicationViewModel bzw. MainPageViewModel überall hin durch.

    Danke Euch

    EDIT: achso, alle Hinweise im Netz gehen immer von einer Hauptpage aus, die dann Unterseiten haben kann, bei mir sind es aber 3 Hauptpages wovon nur eine Unterseiten hat.
    Bei einer einzigen Hauptpage käme man nämlcih komplett ohne zusätzlicher Methode aus, alleine durch die WPF, aber das ist hier nicht gegeben.
    Dateien
    "Hier könnte Ihre Werbung stehen..."
    Na das sieht doch gut aus.

    OK, die Interfaces sind Fleisaufgaben und eine Basisklasse hätte gereicht aber da ich ja auch ein Fan von Interfaces bin hätte ich jetzt nix daran auszusetzen.
    Du hast auf jeden Fall das Prinzip verstanden und wie die WPF mit DataTemplates umgeht.

    Und blickt man da mal durch ist es auch nicht weiter schlimm finde ich und im Gegensatz du einem "Messenger-System" kannst du solch ein Konstrukt auch z.b. in einem Klassendesigner abbilden und kannst somit die Übersicht bei größeren Projekten besser behalten. Und wie man sieht ist es auch in Sachen performance auch kein Problem.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##