Hallo Miteinander,
gibt es mit der WPF und C# eine Möglichkeit ein eigenes "TabControl" zu erstellen welches zum umschalten der Pages nicht den TabHeader verwendet sondern einen TreeView und das ganze sollte wenn möglich auch noch kompatibel sein mit dem Visual Studio Designer damit ich gleich Seiten hinzufügen kann und diese bearbeiten.
Gruß
Hi!
Ich hab hier mal eine Lösung, die geht davon aus, dass deine TabItems je einen spezifischen Datentyp anzeigen sollen - das entspräche jdfs. der Idee von MVVM - hinter jedem TabItem stünde also ein Viewmodel.
Als Viewmodels nehme ich mal 3 scheinbar ähnliche Klassen - inne Realität wären die natürlich total unterschiedlich:
public class DataClass1 {
public string Data { get { return "DataClass1_Data"; } }
}
public class DataClass2 {
public string Data { get { return "DataClass2_Data"; } }
}
public class DataClass3 {
public string Data { get { return "DataClass3_Data"; } }
}
Dann gilt es, die Viewmodels in eine hierarchisch Ordnung zu bringen. Dafür habe ich ein sehr einfaches Objekt erfunden, mit dem man Trees zusammenstöpseln kann:
public class Hirarchy : List<Hirarchy> {
public string Name { get; set; }
public object Item { get; set; }
}
und nun de Xaml:
<Window x:Class="WpfBug.Views.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
xmlns:vm="clr-namespace:WpfBug.ViewModel"
Width="600" Height="300">
<StackPanel Orientation="Horizontal">
<TreeView x:Name="tv" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:Hirarchy}" ItemsSource="{Binding}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemsSource>
<vm:Hirarchy>
<vm:Hirarchy Name="h00">
<vm:Hirarchy.Item>
<vm:DataClass1/>
</vm:Hirarchy.Item>
</vm:Hirarchy>
<vm:Hirarchy Name="h01" >
<vm:Hirarchy.Item>
<vm:DataClass2/>
</vm:Hirarchy.Item>
<vm:Hirarchy Name="h010" >
<vm:Hirarchy.Item>
<vm:DataClass3/>
</vm:Hirarchy.Item>
</vm:Hirarchy>
<vm:Hirarchy Name="h011">
<vm:Hirarchy.Item>
<vm:DataClass3/>
</vm:Hirarchy.Item>
</vm:Hirarchy>
</vm:Hirarchy>
<vm:Hirarchy Name="h02" >
<vm:Hirarchy.Item>
<vm:DataClass1/>
</vm:Hirarchy.Item>
</vm:Hirarchy>
</vm:Hirarchy>
</TreeView.ItemsSource>
</TreeView>
<ContentPresenter Content="{Binding ElementName=tv, Path=SelectedItem.Item}" MinWidth="10">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type vm:DataClass1}">
<TextBlock Text="{Binding Path=Data}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:DataClass2}">
<TextBlock Text="{Binding Path=Data}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:DataClass3}">
<TextBlock Text="{Binding Path=Data}" />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</StackPanel>
</Window>
Der Treeview bekommt also eine Hirarchy als ItemsSource, in die weitere Hirarchies eingeschachtelt sind. Die eingeschachtelten Hirarchies haben als Item eine Instanz der gewünschten Viewmodel-Klasse.
Der ContentPresenter bindet seinen Content an Treeview.SelectedItem.Item - also an die angewählte Viewmodel-Instanz.
Das ist etwas unsauber (und wird vom Designer nicht unterstützt), denn Treeview.SelectedItem ist vom Typ Object, und hier weiter auf die Property Item zu binden geht nur, weil ich weiß, dass der Treeview nur Hirarchy-Elemente enthält - und die haben ja die Item-Property.
In den Ressourcen des ContentPresenters definiere ich 3 DataTemplates, die auf die 3 möglichen Typen matchen. Die Inhalte der Templates sind nur hier identisch, in realiter hätte man vmtl. 3 unterschiedliche UserControls, passend zu den Viewmodel-Datentypen.
Das ist der Witz an ContentControls, dass man in den Ressourcen einfach DataTemplates für verschiedene Typen definieren kann, und Wpf guckt dann, welches davon aufs Objekt anzuwenden ist.
Die Tree-Nodes h010 und h011 beinhalten als Item übrigens beide DataClass3, aber es sind 2 indiv. Instanzen, die auch unterschiedliche Daten halten könnten. Entsprechend h01 und h02.
Der frühe Apfel fängt den Wurm.
Danke für die schnelle Antwort aber damit ist das Problem noch nicht ganz gelöst eigentlich möchte ich ein eigenes UserControl erstellen welches einen TreeView enthält und wo ich im Designer einfach Items hinzufügen kann und wenn ich ein bestimmtes Item im TreeView anwähle (nicht zur Laufzeit des Programms sondern immer noch zur Designzeit) soll er mir soll er mir das dazugehörige Grid anzeigen worauf ich meine anderen Controls anbringen kann.