Warum das?
MainWindow.xaml:
<Window x:Class="MVVMProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Content="{Binding}"/>
</Grid>
</Window>
Lassen Sie Ihre ExampleView.xaml wie folgt einrichten:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<Grid>
<ActualContent/>
</Grid>
</DataTemplate>
</ResourceDictionary>
Und erstellen Sie das Fenster wie folgt:
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
MainWindow app = new MainWindow();
ExampleVM context = new ExampleVM();
app.DataContext = context;
app.Show();
}
}
Wann geht das so?
App.xaml: (Startfenster / Ansicht einstellen)
<Application x:Class="MVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="ExampleView.xaml">
</Application>
ExampleView.xaml: (ein Fenster, kein ResourceDictionary)
<Window x:Class="MVVMProject.ExampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
>
<Window.DataContext>
<vms:ExampleVM />
</Window.DataContext>
<Grid>
<ActualContent/>
</Grid>
</Window>
Im Wesentlichen ist es "View as DataTemplate" (VaD) vs. "View as Window" (VaW)
Hier ist mein Verständnis des Vergleichs:
- VaD: Ermöglicht das Wechseln der Ansicht, ohne das Fenster zu schließen. (Dies ist für mein Projekt nicht wünschenswert)
- VaD: VM weiß absolut nichts über die Ansicht, während sie in VaW (nur) in der Lage sein muss, sie beim Öffnen eines anderen Fensters zu instanziieren
- VaW: Ich kann meine xaml tatsächlich im Designer sehen (ich kann nicht mit VaD, zumindest in meinem aktuellen Setup).
- VaW: Funktioniert intuitiv beim Öffnen und Schließen von Fenstern. Jedes Fenster hat (ist) eine entsprechende Ansicht (und ViewModel)
- VaD: ViewModel kann die anfängliche Fensterbreite, -höhe, -anpassbarkeit usw. über Eigenschaften weitergeben (während sie in VaW direkt im Fenster festgelegt werden).
- VaW: Kann FocusManager.FocusedElement einstellen (nicht sicher, wie in VaD)
- VaW: Weniger Dateien, da meine Fenstertypen (z. B. Multifunktionsleiste, Dialogfeld) in ihre Ansichten integriert sind
Also, was ist hier los? Kann ich meine Fenster nicht einfach in XAML erstellen, über die Eigenschaften der VM sauber auf ihre Daten zugreifen und damit fertig sein? Der Code-Behind ist der gleiche (praktisch Null).
Ich habe Probleme zu verstehen, warum ich das gesamte View-Material in ein ResourceDictionary mischen sollte.
Antworten:
Benutzer verwenden
DataTemplates
diese Methode, wenn sie die Ansicht je nach ViewModel dynamisch wechseln möchten:So,
Wenn
Window.DataContext
es sich um eine Instanz von handeltVM1
,View1
wird Folgendes angezeigt:und wenn
Window.DataContext
ist eine Instanz vonVM2
,View2
wird dann angezeigt.Zugegeben, es macht überhaupt keinen Sinn, wenn nur 1 Ansicht erwartet und nie geändert wird.
quelle
Da die Ansichtsmodelle in VaD nichts über die Ansichten wissen, können Sie eine voll funktionsfähige Anwendung erstellen, die ausschließlich aus Ansichtsmodellen und keinen Ansichten besteht. Dies führt zu der Möglichkeit, eine Anwendung zu schreiben, die vollständig vom Code gesteuert werden kann. Dies führt wiederum zu der Möglichkeit, Integrationstests ohne die GUI durchzuführen. Integrationstests über die GUI sind bekanntermaßen fragil - während Tests über Ansichtsmodelle robuster sein sollten.
quelle
Aus meiner persönlichen Erfahrung: Beide Arbeitsmodelle sind verfügbar, je nachdem, was Sie möchten und je nach den Anwendungsanforderungen. Die Idee dahinter
VaD
ist, den Inhalt und den Container zu entschlüsseln. Wenn Sie implementierenVaD
, können Sie diese Vorlage (standardmäßig) verwenden, wenn Sie ein Element dieses Typs anzeigen. Sie können es inItemsControls
(Listen, Listenansichten, Raster usw.) undContentControls
nur zum Erstellen von Bindungen verwenden. Wie Sie sagten,VaD
funktioniert das Wechseln des Fensterinhalts, ohne ein neues zu schließen und zu öffnen. Sie können die Ansicht auch mit definierenUserControls
, dann die Kontrolle über fokussierte Elemente übernehmen und den Code dahinter verwalten. Ihre Datenvorlage könnte also folgendermaßen aussehen:Sie können auch
UserControl
Abhängigkeitseigenschaften festlegen, die den Job erleichtern, da Sie Bindungen zulassen und die App entkoppeln können.Wenn Ihre App jedoch keine dynamische Inhaltsumschaltung erfordert, ist es natürlich in Ordnung, sie
VaW
für das Hauptfenster oder ein anderes Fenster zu verwenden. In der Tat können Sie beideVaW
und verwendenVaD
. Letzteres kann für innere Elemente in der App verwendet werden, für die keine Fenster erforderlich sind. Sie entscheiden, was für Sie besser ist, abhängig von den Anwendungsanforderungen und der Zeit, die für die Entwicklung der App zur Verfügung steht. Hoffe diese persönliche Erfahrung hilft ...quelle