有时候使用datagrid的列表展示数据的时候 ,为了显示数据的历史变迁,可以在RowDetails中设置和主表列相同的一个DataGrid,但是为了美观的话,要让主表和详细表列保持相同宽度,并不能简单的使用绑定的方式实现,因为DataGrid中的类不在视觉书上,具体原因可以参考我的另一篇文章:WPF MVVM绑定DataGrid的列的显隐性解决方案。下面直接上代码:
首先要有一个类似代理的东西:
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
然后定义的实体如下:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<Person> Children { get; set; }
}
界面:
<Window x:Class="WpfApp1.DataGridRowDetailDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="DataGridRowDetailDemo" Height="450" Width="800">
<Grid>
<DataGrid x:Name="dg" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding ElementName=dg}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="colum1" Header="姓名" Binding="{Binding Name}"/>
<DataGridTextColumn Header="年龄" Binding="{Binding Age}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="{Binding Children}" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="{Binding Source={StaticResource proxy},Path=Data.Columns[0].ActualWidth,Mode=OneWay}"/>
<DataGridTextColumn Header="年龄" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
数据源赋值如下:
List<Person> persons = new List<Person>()
{
new Person
{
Name="Parent",
Age=50,
Children=new List<Person>
{
new Person
{
Name="Son",
Age=28
}
}
}
};
dg.ItemsSource = persons;
如此即可实现。
源码