表示
讓我們來定義一些類作爲模型爲我們的嵌套控件。它基本上是一棵樹,那裏的兒童傳播到他們的父母他們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;
}
主視圖模型
我們需要一些主視圖模型將:
- 含有這種TabItemModels
- 提供選定的tabitemmodel屬性以與樹視圖中的selectedItem進行互操作
代碼:
public class TabsViewModel
{
public TabsViewModel()
{
this.Items = GetItems();
}
private TabItemModel _SelectedItem;
public TabItemModel SelectedItem
{
get
{
return this._SelectedItem;
}
set
{
if (value == this._SelectedItem)
return;
if (value != null)
{
if (this._SelectedItem != null)
this._SelectedItem.IsSelected = false;
value.IsSelected = true;
}
this._SelectedItem = value;
}
}
public ObservableCollection<TabItemModel> Items
{
get;
private set;
}
private ObservableCollection<TabItemModel> GetItems()
{
return new ObservableCollection<TabItemModel>()
{
new TabItemModel("Tab 1",
new TabItemModel[]
{
new TabItemModel("Tab 1 - SubTab 1"),
new TabItemModel("Tab 1 - SubTab 2")
}),
new TabItemModel("Tab 2",
new TabItemModel[]
{
new TabItemModel("Tab 2 - SubTab 1"),
new TabItemModel("Tab 2 - SubTab 2")
}),
new TabItemModel("Tab 3",
new TabItemModel[]
{
new TabItemModel("Tab 3 - SubTab 1"),
new TabItemModel("Tab 3 - SubTab 2")
})
};
}
}
代碼隱藏
public MainWindow()
{
InitializeComponent();
this.DataContext = new TabsViewModel();
}
XAML
這是最漂亮的東西。我是無法到:
- 創建正常的層級嵌套TabControls。
- 連接他們的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>
它採用混合行爲類從this SO answer允許綁定到TreeView的SelectedItem屬性(你將需要添加System.Windows.Interactions.dll
到項目,並xmlns:blend="http://schemas.microsoft.com/expression/2010/interactivity"
您XAML)
PS:我會盡量解決在XAML節中描述的問題,但現在它是我可以提出最好的。