Laden...

MVVM: Wie realisiere ich eine Frame-Navigation?

Erstellt von hypersurf vor 13 Jahren Letzter Beitrag vor 7 Jahren 8.493 Views
H
hypersurf Themenstarter:in
523 Beiträge seit 2008
vor 13 Jahren
MVVM: Wie realisiere ich eine Frame-Navigation?

Hallo Leute,

in meiner Anwendung gibt es ein Hauptfenster mit einem Bereich (Frame) in dem verschiedene Pages dargestellt werden sollen. Das Hauptfenster ist ein ViewModel, die Pages auch.

Da bisher nur die Oberfläche grob designed wurde, habe ich zur Navigation einfach die Source-Eigenschaft des Frames an das ViewModel gebunden.

Source="{Binding Path=CurrentFramepage}"

Das klappt natürlich, bringt mir aber im MVVM-Pattern nichts, weil ich Daten an die ViewModels der Pages weitergeben muss. Ich bräuchte einen kleinen Denkanstoß wie kann man sowas im MVVM realisieren kann. Mr. Google konnte mir nicht wirklich helfen.

Ich hatte schonmal versucht die DataContext-Eigenschaft des Frames mit der Page zu füttern, das klappt aber nicht (es wird gar nichts dargestellt).

T
15 Beiträge seit 2008
vor 13 Jahren

Hallo hypersurf,

wenn ich den Sacha Barber (Entwickler von Cinch) richtig verstanden habe macht man das so:
Du hast eine MainView auf der du eine Listbox oder TabControl hast. Dieses TabControl hat ein Binding auf ein Property (ObservableCollection) in einem ViewModel, welches dann mit Views befüllt wird.
Wenn du also ein Tabcontrol verwendest, kannst du auf jedem Tabreiter eine eigene View anzeigen.
Und diese Logik kannst du auf die Navigationsleiste ja auch anwenden.
Wenn du jetzt einem anderen "Frame" mitteilen willst, dass er was anderes anzeigen soll, dann geschieht das über sog. Mediatormessages.

Ich hoffe das einigermassen verständlich erkärt zu haben...
Das alles setzt logischerweise Cinch oder ein ähnlich mächtiges MVVM Framework vorraus.

Als Tipp:
Cinchv2 - Mediator Messaging

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo hypersurf,

ich verstehe ehrlich gesagt nicht, wo dein Problem ist. Suchst du sowas wie ein Wizard für das MVVM-Pattern oder eine Art Breadcrumb-Bar? Hilft dir das oder das weiter?

zero_x

H
hypersurf Themenstarter:in
523 Beiträge seit 2008
vor 13 Jahren

Ich habe das Problem jetzt mittels eines Controlpresenters gelöst und verwende anstatt Pages jetzt UserControls.


    <Window.Resources>
        <DataTemplate DataType="{x:Type local:KapaAnzeigeViewModel}">
            <local:ViewKapaAnzeige/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:UnverplantFilterViewModel}">
            <local:ViewUnverplantFilter/>
        </DataTemplate>
    </Window.Resources>


            <ContentPresenter Name="MyContent" Grid.Column="2" Grid.Row="0" 
                              Content="{Binding Path=CurrentContent}"/>

Das ViewModel des Hauptfensters enhält eine Eigenschaft CurrentContent die vom Typ der Basisklasse meiner ViewModels ist:


        private BaseViewModel _CurrentContent;
        public BaseViewModel CurrentContent
        {
            get { return _CurrentContent; }
            set { 
                    _CurrentContent = value;
                    ValueChanged("CurrentContent");
                }
        }


KapaAnzeigeViewModel model = new KapaAnzeigeViewModel();
this.CurrentContent = model;

So funktioniert das ganze wie ich es mir vorgestellt habe.

Jetzt habe ich nur noch ein sehr merkwürdiges Problem mit dem Visual Studio 2008. Der WPF-Designer in dem die Vorschau des Fensters angezeigt wird zeigt immer einen "Fehler beim Laden" an. Dieser kommt anscheinend von den DataTemplates. Kompiliert wird zwar mit 0 Fehlern und 0 Warnungen, eine Fehlermeldung erhalte ich aber trotzdem:

Fehlermeldung:
Fehler 1 Die Instanz des ViewKapaAnzeige-Typs konnte nicht erstellt werden.

Kommentiere ich die Datatemplates aus, funktioniert die Vorschau wieder 🤔

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo hypersurf,

startet die Anwendung? Wird zur Laufzeit das DataTemplate richtig angezeigt? Es kann gut sein, dass es einfach ein Fehler vom Designer ist.

zero_x

H
hypersurf Themenstarter:in
523 Beiträge seit 2008
vor 13 Jahren

Ja, die Anwendung funktioniert tadellos. Scheint wohl mal wieder ein Bug vom Designer zu sein... 😭

5.299 Beiträge seit 2008
vor 13 Jahren

oder das ViewKapaDings ist nicht Designerfest programmiert.

Vlt. ists ja abhängig von einem Wert im DataContext, und der Designer stellt den nicht zur Verfügung.

Der frühe Apfel fängt den Wurm.

H
33 Beiträge seit 2009
vor 7 Jahren

So wie es hypersurf in seinem Beitrag vom 04.02.2011, 11:54 Uhr beschrieben hat, habe ich ebenfalls UserControls innerhalb eines MainWindows zur Anzeige gebracht.

Ich möchte jetzt noch den UserControls beim Aufruf durch einen MainWindow-Button Parameter mitgeben?

Dazu habe ich Folgendes gemacht:
In dem an den Button gebundenen Command steht


InputViewModel viewModel = new InputViewModel(SelectedGroup);
this.CurrentContent = viewModel;

Der Aufruf klappt noch.

Jetzt wird aber danach noch der Konstruktor InputViewModel() gerufen. Ich vermute, dass das passiert, weil ich in InputView.xaml den DataContext auf InputViewModel setze. Denn wenn ich das Statement weglasse, bekomme ich eine Fehlermeldung.

Wie muss ich es nun richtig machen, damit der Parameter ankommt?

Gruß, Harry B.

Kaum macht man 's richtig, schon funktioniert 's!

M
177 Beiträge seit 2009
vor 7 Jahren

Geht es darum, dass du so etwas selbst implementierst oder möchtest du einfach auch so eine Funktion haben?

Bei letzterem würde ich dir raten ein MVVM Framework wie Prism ein zu setzen, die bringen all diese Funktion mit sich. (und theoretisch könntest du dir auch dessen Implementierung als Referenz ansehen)

Siehe dazu:
Navigation Using the Prism Library for WPF

R
74 Beiträge seit 2006
vor 7 Jahren

das ist aber nicht verwandt mit
Prism patterns & practices Developer Center
oder ?

Die Quellcodes sind es jedenfalls nicht

M
177 Beiträge seit 2009
vor 7 Jahren

Doch. Das Prism Framework wurde mittlerweile von MS an Brian bzw. an die Online Community übergeben.

H
33 Beiträge seit 2009
vor 7 Jahren

Geht es darum, dass du so etwas selbst implementierst ... Ja, darum geht es.

Gruß, Harry B.

Kaum macht man 's richtig, schon funktioniert 's!