WPF/Windows Store App 下实现ComboBox的Master-Detail 两层/三层级联绑定
WPF下的两层级联绑定
要绑定的数据结构如下,一个Category包含多个SubCategory:
public class Category { public string Name { get; set; } public ObservableCollection<SubCategory> SubCategories { get; set; } } public class SubCategory { public int Id { get; set; } public string SubCategoryName { get; set; } }
Code-behind初始化测试数据:
View Code
public partial class AssetEditor : Window { public ObservableCollection<Category> CategorieCollection { get; set; } public AssetEditor() { InitializeComponent(); CategorieCollection = new ObservableCollection<Category>(); CategorieCollection.Add(new Category() { Name = "Cate1", SubCategories = new ObservableCollection<SubCategory>() }); CategorieCollection.Add(new Category() { Name = "Cate2", SubCategories = new ObservableCollection<SubCategory>() }); CategorieCollection[0].SubCategories.Add(new SubCategory() { Id = 0, SubCategoryName = "sub1" }); CategorieCollection[1].SubCategories.Add(new SubCategory() { Id = 0, SubCategoryName = "sub2" }); cmbCategoryName.DataContext = CategorieCollection; } }
XAML里绑定:
<ComboBox Grid.Row="0" Grid.ColumnSpan="2" Grid.Column="1" Name="cmbCategoryName" ItemsSource="{Binding}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedItem="{Binding Path=SubCategories}" /> <ComboBox Grid.Row="0" Grid.Column="5" Grid.ColumnSpan="3" Name="cmbSubCategory" DataContext="{Binding ElementName=cmbCategoryName,Path=SelectedItem,Mode=OneWay}" ItemsSource="{Binding Path=SubCategories, Mode=OneWay}" DisplayMemberPath="SubCategoryName" SelectedValuePath="Id" />
当cmbCategoryName选中的Category改变,cmbSubCategory的 SubCategory集合也会随之改变。
Windows Store App下的三层级联绑定
两者的XAML和C#代码几乎一致,不同的是,这次我们改用一个递归的数据结构实现主从数据关系
public class Hierachy<T> where T : class { public int Id { get; set; } public string Name { get; set; } public ObservableCollection<T> Elements { get; set; } }
Code Behind
1 public sealed partial class MainPage : Page 2 { 3 public ObservableCollection<Hierachy<Hierachy<string>>> CategorieCollection { get; set; } 4 public MainPage() 5 { 6 this.InitializeComponent(); 7 CategorieCollection = new ObservableCollection<Hierachy<Hierachy<string>>>(); 8 CategorieCollection.Add(new Hierachy<Hierachy<string>>() 9 { 10 Name = "Cate1", 11 Elements = new ObservableCollection<Hierachy<string>>() 12 }); 13 14 CategorieCollection.Add(new Hierachy<Hierachy<string>>() 15 { 16 Name = "Cate2", 17 Elements = new ObservableCollection<Hierachy<string>>() 18 }); 19 20 CategorieCollection[0].Elements.Add(new Hierachy<string>() 21 { 22 Name = "sub1", 23 Elements = new ObservableCollection<string>() { "element 1", "element 2" } 24 }); 25 26 CategorieCollection[1].Elements.Add(new Hierachy<string>() 27 { 28 Name = "sub2", 29 Elements = new ObservableCollection<string>() { "element 3", "element 4" } 30 }); 31 32 cmbCategoryName.DataContext = CategorieCollection; 33 } 34 35 } 36 37 38 public class Hierachy<T> where T : class 39 { 40 public int Id { get; set; } 41 public string Name { get; set; } 42 public ObservableCollection<T> Elements { get; set; } 43 } 44 }
XAML
<Page x:Class="MyStoreApp1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyStoreApp1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" Width="500" Height="300"> <Grid.RowDefinitions> <RowDefinition Height="25"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="150"/> <ColumnDefinition Width="150"/> <ColumnDefinition Width="150"/> </Grid.ColumnDefinitions> <ComboBox Grid.Column="0" Name="cmbCategoryName" ItemsSource="{Binding}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedItem="{Binding Path=Elements}" /> <ComboBox Grid.Column="1" Name="cmbSubCategory" DataContext="{Binding ElementName=cmbCategoryName,Path=SelectedItem,Mode=OneWay}" ItemsSource="{Binding Path=Elements, Mode=OneWay}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedItem="{Binding Path=Elements}" /> <ComboBox Grid.Column="2" Name="cmbElements" DataContext="{Binding ElementName=cmbSubCategory,Path=SelectedItem,Mode=OneWay}" ItemsSource="{Binding Path=Elements, Mode=OneWay}" /> </Grid> </Page>