我在github.com创建了一个演示项目
输出:
XAML 代码:具有两列且每列包含一个 DataGrid 的网格
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DataGrid Name="basketNameDataGrid" AutoGenerateColumns="False" CanUserResizeRows="False"
CanUserAddRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Height" Value="{Binding RowHeight}"></Setter>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Basket">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" VerticalAlignment="Center"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid Name="itemDataGrid" Grid.Column="1" AutoGenerateColumns="False" HeadersVisibility="Column"
CanUserResizeRows="False" CanUserAddRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Height" Value="20"></Setter>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Item Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name, Mode = OneWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Price" Binding="{Binding Price, Mode = OneWay}" CanUserSort="False"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
C# 代码 - 结构化数据分为三个类。
(移除构造函数以减少代码行)
class Item
{
public Name {get;}
public Price {set;}
}
class Basket : List<Item>
{
public Name {get;}
}
class BasketCollection : List<Basket>
{
}
MainWindow.cs 中的代码 - 填充数据并分配给 DataGrids。
public MainWindow()
{
InitializeComponent();
//// Get some data to show in View
var baskets = GetData();
int rowHeight = 20; //// itemDataGrid row height is 20 in xaml
//// Create a list of annonymous type with properties Name an RowHeight.
//// RowHeight = Height of one row * number of items in current basket.
var basketNameData = baskets.Select(x => new { Name = x.Name, RowHeight = rowHeight * x.Count });
//// Assign data to first DataGrid
basketNameDataGrid.ItemsSource = basketNameData.ToList();
//// Get list of all Items in all baskets and assign as ItemsSource to second datagrid
itemDataGrid.ItemsSource = baskets.SelectMany(basket => basket).ToList();
}
/// <summary>
/// Gets some data to bind to view
/// </summary>
/// <returns>Basket Collection</returns>
private BasketCollection GetData()
{
var baskets = new BasketCollection();
var fruitBasket = new Basket("Fruit");
fruitBasket.Add(new Item("Alphonso Mango", 80));
fruitBasket.Add(new Item("Nagpur Orange", 10));
fruitBasket.Add(new Item("Dragon Fruit", 50));
var vegetableBasket = new Basket("Vegetable");
vegetableBasket.Add(new Item("Brinjal", 5));
vegetableBasket.Add(new Item("Broccoli", 5));
vegetableBasket.Add(new Item("Onion", 3));
baskets.Add(fruitBasket);
baskets.Add(vegetableBasket);
return baskets;
}
注意:此解决方案实际上并不合并单元格,而是创建这样的视觉
效果。你可以试试这个。 Demo 使用两个 DataGrid 控件。
增加第一个DataGrid的行高以创建合并单元格效果。
替代方案: ReoGrid 是 MS Excel 兼容控件,支持 merge/unmerge 单元格功能,如 Excel。 ReoGrid 声称是免费和开源的。它不支持数据绑定,但它有support for DataTable。