Die ComboBox
würde eine ObservableCollection
der Frame-Elemente von Ihrem Hauptansichtsmodell ausgestellt anzeigen, und das Viewmodel wird eine andere Eigenschaft für das ausgewählte Element haben.
Ihr ViewModel und die Frame-ViewModels erben alle von einer ViewModelBase
-Klasse, die INotifyPropertyChanged
implementiert, und vielleicht ein paar andere Sachen.
So, C#:
public ObservableCollection<ViewModelBase> FrameItems { get; protected set; }
private ViewModelBase _selectedFrameItem;
public ViewModelBase SelectedFrameItem {
get { return _selectedFrameItem; }
set {
value = _selectedFrameItem;
// Defined in ViewModelBase
OnPropertyChanged();
}
}
Ihr Hauptansichtsmodell wird FrameItems
in seinem Konstruktor füllen:
public MainViewModel()
{
FrameItems = new ObservableCollection<ViewModelbase> {
new IceCreamMenu(),
new SmurfOptions(),
new MagicSparklePonyFourierTransformConfiguration()
};
}
Jeder Frame Artikel ist eine Unterklasse von ViewModelBase
. Es macht Eigenschaften mit Benachrichtigungen verfügbar, einschließlich ObservableCollections
eines beliebigen Satzes von untergeordneten Dingen, die es möglicherweise hat. Und wir werden es anzeigen, indem wir ein Datamaplate dafür in ein bisschen schreiben.
Nehmen wir an, Sie haben Ihrer ViewModelBase
Klasse eine String Title { get; set; }
Eigenschaft gegeben. Oder vielleicht möchten Sie eine Unterklasse von ViewModelBase
schreiben, die Title
einführt; Ihr Anruf. Für jetzt lassen Sie uns es zur Einfachheit in ViewModelBase
setzen.
XAML - das lässt das Layout aus, aber Sie brauchen das hier nicht.
<ComboBox
ItemsSource="{Binding FrameItems}"
SelectedItem="{Binding SelectedFrameItem}"
DisplayMemberPath="Title"
/>
<Frame Content={Binding SelectedFrameItem}" />
in Ordnung, aber wie auf der Erde weiß, ist das, was mit SelectedFrameItem
zu tun?
Einfach! Schreiben Sie ein Ressourcenwörterbuch mit dem Namen, sagen wir ViewModelDataTemplates.xaml
, und verschmelzen Sie es in App.xaml
, so dass der Inhalt in jedem XAML in Ihrer Anwendung "sichtbar" ist.
App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Source is a relative path from project root directory -->
<ResourceDictionary Source="ViewModelDataTemplates.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
... plus was auch immer Thema Sachen oder was auch immer.
Definieren Sie in ViewModelDataTemplates.xaml
Datenvorlagen für Ihre Rahmenelementklassen.
Sagen Sie bitte ein IceCreamMenu
Ansichtsmodell haben, mit einer Sammlung von Flavors
public ObservableCollection<IceCreamFlavor> Flavors { get; protected set; }
... und SelectedFlavor
. Sie würden den Namespace vm
entsprechend mit einem xmlns:vm
-Attribut im Ressourcenwörterbuch definieren.
ViewModelDataTemplates.xaml
<DataTemplate DataType="{x:Type vm:IceCreamMenu}">
<Grid>
<ListBox
ItemsSource="{Binding Flavors}"
SelectedItem="{Binding SelectedFlavor}"
/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:IceCreamFlavor}">
<StackPanel Orientation="Horizontal">
<Border
Height="20"
Width="20"
Margin="4"
Background={Binding Color, Converter={StaticResource ColorToBrushConverter}}"
/>
<Label Content="Name" />
</StackPanel>
</DataTemplate>
Wenn Sie UserControls
vorhandene haben, die Sie über Datatemplates verwenden möchten, das ist einfach: Sagen Sie bitte eine NotesTabView
UserControl
haben, die einen Blick für Ihren NotesTabViewModel
ist, könnten Sie definieren ein Datatemplate wie folgt aus:
<DataTemplate DataType="{x:Type vm:NotesTabViewModel}">
<vw:NotesTabView />
</DataTemplate>
Wenn ich dies tue, wähle ich ein Element aus dem Kombinationsfeld, es ändert den Inhalt des Rahmens zu nur dem Namen des Ansichtsmodells, das es instanziiert, als wenn es nur eine .tostring() -Methode darauf macht. Die gesamte DataTemplate definiert, wie die Daten korrekt angezeigt werden? Nun die Sache, wenn ich eine separate Ansicht für jede Seite bereits erstellt haben, so dass es nur in die richtige Ansicht wechseln muss – Tbooty
Klingt, als ob es die Datatemplate für den Viewmodel Typ nicht finden Sie in den Rahmen. Verschmelzen Sie Ihre datatemplates.xaml in App.xaml? –
@Tbooty App.xaml zu meiner Antwort hinzugefügt –