2016-03-29 8 views
0

Ich benutze Prisms viewlocator, um View und ViewModel zu verbinden, und ich folge der Konvention, indem ich die View innerhalb des View-Ordners und ViewModel innerhalb des viewmodel-Ordners platziere und Suffix ViewModel zum Namen der viewmodel-Klasse hinzufüge. Alles funktioniert gut. Ich habe mich gerade gefragt, wie man mehrere Ansichtsmodelle mit einer einzigen Ansicht verbindet?Wie verbindet man mehrere ViewModels mit einer View mit dem Prism Viewlocator?

Zum Beispiel habe ich:

Ausblick: CustomerView und in XAML ich einfach nutzen: prism:ViewModelLocator.AutoWireViewModel="True"

ViewVodel: CustomerViewModel

jetzt will ich CustomerViewModel2 hinzufügen, aber es wird nicht zu funktionieren, weil sie nicht mit dem Namen der Ansicht übereinstimmen

+1

Was versuchen Sie zu erreichen? Eine View verfügt nur über eine 'DataContext'-Eigenschaft, so dass sie nur ein View-Modell haben kann. Natürlich können untergeordnete Ansichten oder sogar Teile Ihrer Ansicht unterschiedliche Ansichtsmodelle haben, dies kann jedoch nicht mit dem View Model Locator von PRISM durchgeführt werden. Sie müssen Data Templating oder View Injection/Regions dafür verwenden. – dymanoid

+0

Meine ViewModel-Klasse wird zu groß und verwirrend, deshalb wollte ich sie in mehrere ViewModels aufteilen, ähnlich wie Models. – Ivan

+0

Das klingt nach einem guten Refactoring Ihres Codes. Etwas Code in andere Klassen zu verschieben, wo es Sinn macht, könnte die Verwirrung etwas reduzieren. Verwenden Sie mindestens Regionen, um den Code zu gruppieren, damit Sie ihn bei Bedarf reduzieren/erweitern können. –

Antwort

0

Richten Sie Ihre Ansichtsmodelle als partielle Klassen ein.

+1

Technisch ist diese Antwort inkorrekt, weil die partielle Klassendefinitionen eine einzelne Klasse beschreiben - es wird nur ein Objekt instanziiert werden. Während dies für OP eine Lösung sein könnte, ist es im Allgemeinen keine. – dymanoid

1

Sie könnten untergeordnete Ansichtsmodelle als Eigenschaften des Hauptansichtsmodells für die Seite t verfügbar machen Stellen Sie die Pfade zum untergeordneten Ansichtsmodell in Ihren Bindungen mit dem Namen der Eigenschaft voran.

2

Wie ich bereits in meinem Kommentar erwähnt habe, gibt es keine Möglichkeit, eine einzelne Ansicht direkt mit mehreren (gleichstufigen) Ansichtsmodellen zu verbinden.

Sie müssen Ihre Ansicht in eine Master- und (mehrere) untergeordnete Ansichten aufteilen (entweder logisch in XAML oder physisch, indem untergeordnete Ansichten in separate UserControl s verschoben werden).

Hier sind meine Vorschläge.

  1. Verwenden Sie PRISM-Regionen.

eine Master-Ansicht definieren, die die Regionen beinhaltet: Ansichten erstellen

<Window> 
    <StackPanel Orientation="Vertical"> 
     <ContentControl prism:RegionManager.RegionName="Region1"/> 
     <ContentControl prism:RegionManager.RegionName="Region2"/> 
    </StackPanel> 
</Window> 

Kindes, das "eingefügt" wird (in PRISM Terminologie - injizierte) in der Hauptansicht:

<UserControl x:Class="UserControl1"> 
    <Grid/> 
</UserControl> 

<UserControl x:Class="UserControl2"> 
    <Grid/> 
</UserControl> 

Und schließlich müssen Sie in PRISM Ihre Ansichten registrieren, damit sie instanziiert werden können:

Jede dieser untergeordneten Ansichten hat ihr eigenes Ansichtsmodell. Sie können den View Model Locator des PRISM verwenden, um sie automatisch zu verkabeln.

  1. Verwenden Sie das Datentemplate.

Ihre Masteransicht:

<Window> 
<Window.Resources> 
    <DataTemplate DataType="vm:ViewModel1"> 
     <v:UserControl1/> 
    </DataTemplate> 
    <DataTemplate DataType="vm:ViewModel2"> 
     <v:UserControl2/> 
    </DataTemplate> 
</Window.Resources> 
    <ItemsControl ItemsSource="{Binding Items}"/> 
</Window> 

Fügen Sie die untergeordneten Ansicht Modelle in die Items Sammlung Ihrer Master View-Modell, und WPF die Ansichten und Auto-Draht die Ansicht Modelle mit ihnen für Sie erstellen.

class MasterViewModel : BindableBase 
{ 
    public IEnumerable<BindableBase> Items 
    { 
     get { return new[] { new ViewModel1(), new ViewModel2() } 
    } 
} 

Natürlich können Sie DI zum Instanziieren Ihrer Ansichtsmodelle verwenden.

  1. Verwenden Sie das "gestapelte" Ansichtsmodell.

Etwas wie folgt aus:

class MainViewModel : BindableBase 
{ 
    public ViewModel1 ViewModel1 { get; private set; } 
    public ViewModel2 ViewModel2 { get; private set; } 
} 

in der Hauptansicht, werden Sie Ihre Bindungen entsprechend eingerichtet haben.

<Window> 
    <StackPanel> 
     <TextBlock Text="{Binding ViewModel1.SomeValue}"/> 
     <TextBox Text="{Binding ViewModel2.SomeValue}"/> 
    </StackPanel> 
</Window> 
+0

Danke für Ihre ausführliche Antwort. Ich mag die Idee von Regionen sehr, und ich erinnere mich, dass ich versucht habe, sie vorher zu benutzen. Das Problem war, dass die Ansicht, mit der ich arbeite, eine Seite ist, zu der ich navigiere. Also wenn ich das mache: 'regionManager.RegisterViewWithRegion ("Region1", typeof (UserControl1));' dann wird diese Ansicht (Seite) sichtbar, sobald die Anwendung gestartet wird. Ich benutze derzeit 'RegisterForNavigation' Methode, aber diese Art von Konflikten mit 'RegisterViewWithRegion' – Ivan