C# 从嵌套的选项卡控件填充树视图
我正在构建一个设置窗口,左侧有一个C# 从嵌套的选项卡控件填充树视图,c#,wpf,xaml,treeview,tabcontrol,C#,Wpf,Xaml,Treeview,Tabcontrol,我正在构建一个设置窗口,左侧有一个TreeView,右侧有一个TabControl——布局基于Microsoft Visual Studio选项对话框 TabControl有3个TabItems,因此有3个选项卡。每个TabItems都包含一个TabControl,其中有两个TabItems。我计划稍后隐藏TabControl选项卡,但返回到TreeView,它将如下所示: 选项组1 子选项组1 次级方案组2 选项组2 子选项组1 次级方案组2 选项组3 子选项组1 次级方案组2
TreeView
,右侧有一个TabControl
——布局基于Microsoft Visual Studio选项对话框
TabControl
有3个TabItems
,因此有3个选项卡。每个TabItems
都包含一个TabControl
,其中有两个TabItems
。我计划稍后隐藏TabControl
选项卡,但返回到TreeView
,它将如下所示:
- 选项组1
- 子选项组1
- 次级方案组2
- 选项组2
- 子选项组1
- 次级方案组2
- 选项组3
- 子选项组1
- 次级方案组2
树视图中的项目将导致相应的选项卡项目变为活动状态。如何获取Treeview
的选定项/节点,并使所有选项卡控件
做出反应
我怀疑这是否是最好的方法。我必须维护TreeView
项和选项卡(树)项的TabControl
TabItems
..表示
让我们定义一些类作为嵌套控件的模型。它基本上是一棵树,在树中,孩子们将他们的IsSelected
属性的更改传播给他们的父母:
public class TabItemModel : INotifyPropertyChanged
{
private TabItemModel m_parent;
private Boolean m_IsSelected;
public TabItemModel(String name) : this(name, null)
{
}
public TabItemModel(String name, IEnumerable<TabItemModel> children)
{
this.Name = name;
this.Children = new ObservableCollection<TabItemModel>(children ?? Enumerable.Empty<TabItemModel>());
foreach (var child in this.Children)
{
child.m_parent = this;
}
}
public String Name
{
get;
set;
}
public ObservableCollection<TabItemModel> Children
{
get;
private set;
}
public Boolean IsSelected
{
get
{
return this.m_IsSelected;
}
set
{
if (value == this.m_IsSelected)
return;
if (this.m_parent != null)
this.m_parent.IsSelected = value;
this.m_IsSelected = value;
this.OnPropertyChanged();
}
}
protected void OnPropertyChanged([CallerMemberName]String propertyName = null)
{
var propChangedDelegate = this.PropertyChanged;
if (propChangedDelegate == null)
return;
propChangedDelegate(this,
new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
XAML
这是最不漂亮的东西。我无法同时:
创建普通的分层嵌套选项卡控件
将其IsSelected连接到数据模板中IsSelected的绑定项
因此,目前我只能提出以下带有硬编码tabItems的XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TreeView Grid.Row="0" Grid.Column="0"
ItemsSource="{Binding Items}">
<blend:Interaction.Behaviors>
<view:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
</blend:Interaction.Behaviors>
<TreeView.Resources>
<DataTemplate x:Key="tabItemTemplateLeaf">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="tabItemTemplate"
ItemTemplate="{StaticResource tabItemTemplateLeaf}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemTemplate>
<StaticResource ResourceKey="tabItemTemplate"/>
</TreeView.ItemTemplate>
</TreeView>
<TabControl Grid.Row="0" Grid.Column="1">
<TabItem DataContext="{Binding Items[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
<TabItem DataContext="{Binding Items[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
<TabItem DataContext="{Binding Items[2]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
</TabControl>
</Grid>
它使用来自的blend Behavior类来允许绑定到TreeView的SelectedItem属性(您需要将System.Windows.Interactions.dll
添加到您的项目和xmlns:blend=”http://schemas.microsoft.com/expression/2010/interactivity“
到您的XAML)
p.S:我将尝试解决XAML部分中描述的问题,但目前这是我所能提出的最佳方案
public MainWindow()
{
InitializeComponent();
this.DataContext = new TabsViewModel();
}
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TreeView Grid.Row="0" Grid.Column="0"
ItemsSource="{Binding Items}">
<blend:Interaction.Behaviors>
<view:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
</blend:Interaction.Behaviors>
<TreeView.Resources>
<DataTemplate x:Key="tabItemTemplateLeaf">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="tabItemTemplate"
ItemTemplate="{StaticResource tabItemTemplateLeaf}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemTemplate>
<StaticResource ResourceKey="tabItemTemplate"/>
</TreeView.ItemTemplate>
</TreeView>
<TabControl Grid.Row="0" Grid.Column="1">
<TabItem DataContext="{Binding Items[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
<TabItem DataContext="{Binding Items[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
<TabItem DataContext="{Binding Items[2]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}">
<TabControl>
<TabItem DataContext="{Binding Children[0]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
<TabItem DataContext="{Binding Children[1]}" Header="{Binding Name}" IsSelected="{Binding IsSelected}"/>
</TabControl>
</TabItem>
</TabControl>
</Grid>