可以通过设置DataGrid的HierarchyChildTemplate来实现表的主从嵌套,不过这里设置完成后所有嵌套的表的结构都是一样了,但是我需要不一样的结构,由一下代码完成。
注1:DataGrid的嵌套是直接点击后下拉出来的,平时看不出有嵌套的情况。但是我想在要那种树状结构,所以这里直接用了RAD第三方控件的插件,RadGridView,他们都能实现,只是显示的效果有点不一样。
注2:DLL
XAML:
<telerik:RadGridView x:Name="radTree"
ShowGroupPanel="False"
CanUserFreezeColumns="False"
GridLinesVisibility="Both"
IsReadOnly="True"
AutoGenerateColumns="False"
IsFilteringAllowed="False"
RowIndicatorVisibility="Collapsed" Margin="0,2">
<telerik:RadGridView.ChildTableDefinitions>
<telerik:GridViewTableDefinition/>
</telerik:RadGridView.ChildTableDefinitions>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="名称" DataMemberBinding="{Binding Name}" MinWidth="100"/>
<telerik:GridViewDataColumn Header="开始时间" DataMemberBinding="{Binding StartTime}" MinWidth="120" />
<telerik:GridViewDataColumn Header="结束时间" DataMemberBinding="{Binding EndTime}" MinWidth="120" />
</telerik:RadGridView.Columns>
<telerik:RadGridView.HierarchyChildTemplate>
<DataTemplate>
<telerik:RadGridView ItemsSource="{Binding Items}"
ShowGroupPanel="False"
CanUserFreezeColumns="False"
GridLinesVisibility="Horizontal"
IsReadOnly="True"
AutoGenerateColumns="False"
IsFilteringAllowed="False"
ShowColumnHeaders="False" BorderThickness="0">
<telerik:RadGridView.ChildTableDefinitions>
<telerik:GridViewTableDefinition/>
</telerik:RadGridView.ChildTableDefinitions>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" MinWidth="100"/>
</telerik:RadGridView.Columns>
<telerik:RadGridView.HierarchyChildTemplate>
<DataTemplate>
<classes:MyDataGrid DataSources="{Binding Datas}" Visibility="Collapsed"/>
</DataTemplate>
</telerik:RadGridView.HierarchyChildTemplate>
</telerik:RadGridView>
</DataTemplate>
</telerik:RadGridView.HierarchyChildTemplate>
</telerik:RadGridView>
后台:
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
Init();
}
private void Init()
{
var fruit = new List<string> { "苹果", "橘子", "香蕉" };
var municipality = new List<string> { "北京", "天津", "上海", "重庆" };
var province = new List<string> { "黑龙江", "吉林", "辽宁" };
var leafItem1 = new LeafItem { Name = "水果", Datas = CreateNewDatas(fruit) };
var leafItem2 = new LeafItem { Name = "直辖市", Datas = CreateNewDatas(municipality) };
var leafItem3 = new LeafItem { Name = "省份", Datas = CreateNewDatas(province) };
var leaf1 = new Leaf { Name = "总结点1", StartTime = "2013-06-01", EndTime = "2013-06-02", Items = new List<LeafItem> { leafItem1 } };
var leaf2 = new Leaf { Name = "总结点2", StartTime = "2013-06-02", EndTime = "2013-06-03", Items = new List<LeafItem> { leafItem2, leafItem3 } };
radTree.ItemsSource = new List<Leaf> { leaf1, leaf2 };
}
private static List<Dictionary<string, string>> CreateNewDatas(List<string> list)
{
var random = new Random();
var datas = new List<Dictionary<string, string>>();
var count = random.Next(10);
for (var i = 0; i < count; i++)
{
datas.Add(list.ToDictionary(str => str, str => random.Next(50).ToString(CultureInfo.InvariantCulture)));
}
return datas;
}
}
这里为了实现不同的从属表结构,所以自定义了一个控件,继承自DataGrid。这里用到了上一篇里面DataGrid 绑定 字典集合。
public class MyDataGrid : DataGrid
{
#region 数据值
public static readonly DependencyProperty DataSourcesProperty =
DependencyProperty.Register("DataSources", typeof(List<Dictionary<string, string>>), typeof(MyDataGrid), new PropertyMetadata(null));
public List<Dictionary<string, string>> DataSources
{
get { return (List<Dictionary<string, string>>)GetValue(DataSourcesProperty); }
set { SetValue(DataSourcesProperty, value); }
}
#endregion
public MyDataGrid()
{
DefaultStyleKey = typeof(DataGrid);
Loaded += MyDataGrid_Loaded;
}
void MyDataGrid_Loaded(object sender, RoutedEventArgs e)
{
if (DataSources == null || DataSources.Count == 0) return;
var first = DataSources.First();
foreach (var node in first)
{
Columns.Add(new DataGridTextColumn { Header = node.Key, Binding = new Binding(string.Format("[{0}]", node.Key)) });
}
AutoGenerateColumns = false;
ItemsSource = DataSources;
Visibility = Visibility.Visible;
}
}
再设置一个用于绑定的类
public class LeafItem
{
public string Name { get; set; }
public List<Dictionary<string, string>> Datas { get; set; }
public LeafItem()
{
Datas = new List<Dictionary<string, string>>();
}
}
public class Leaf
{
public string Name { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public List<LeafItem> Items { get; set; }
public Leaf()
{
Items = new List<LeafItem>();
}
}