垂直合并 WPF DataGrid 中的单元格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39748090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Merging cells in WPF DataGrid vertically
提问by nickosv
I want to make a DataGridin WPF, where some of the cells will "merge together", if they are alike.
我想DataGrid在 WPF 中创建一个,其中一些单元格将“合并在一起”,如果它们相似的话。
Example:
例子:
+---------+------+-----+
| Country | Name | Age |
+---------+------+-----+
| | Lisa | 24 |
+ +------+-----+
| Danmark | Per | 32 |
+ +------+-----+
| | Hans | 33 |
+---------+------+-----+
| Germany | Mick | 22 |
+---------+------+-----+
Is there any way to achieve this using DataGridusing binding?
有没有办法DataGrid使用绑定来实现这一点?
Thanks a lot in advance.
非常感谢。
采纳答案by AnjumSKhan
Sorry, got buisy with other stuff.
抱歉,忙于其他事情。
Trick to such scenarios is to use the Groupsformed in CollectionViewSourceas the ItemsSourceof a DataGrid. And, use a DataGriditself as the CellTemplateof Column.
这种情况的技巧是使用Groups形成的 inCollectionViewSource作为ItemsSourcea 的DataGrid。并且,使用 aDataGrid本身作为CellTemplateof Column。
Xaml
xml
<Window.Resources>
<CollectionViewSource x:Key="CvsKey">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Country"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DataGrid x:Name="dg" Loaded="dg_Loaded" HorizontalScrollBarVisibility="Disabled" HeadersVisibility="All" Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Country" Width="75">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name" Width="75">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Items}" IsReadOnly="True" AutoGenerateColumns="False" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
DataGrid.Loaded event
DataGrid.Loaded event
private void dg_Loaded(object sender, RoutedEventArgs e)
{
var groups = (this.Resources["CvsKey"] as CollectionViewSource).View.Groups;
dg.ItemsSource = groups;
}
This should get you started.
这应该让你开始。
Output :
输出 :
回答by Prafulla
I have created a demo project on github.com
Output:
我在github.com上创建了一个演示项目
输出:
XAML Code: Grid with two columns and each containing a DataGrid
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# code - There are three classes to structure data. (Removed constructors to reduce code lines)
C# 代码 - 有三个类来构造数据。(删除了构造函数以减少代码行)
class Item
{
public Name {get;}
public Price {set;}
}
class Basket : List<Item>
{
public Name {get;}
}
class BasketCollection : List<Basket>
{
}
Code behind in MainWindow.cs - Populate data and assign to DataGrids.
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;
}
Note:This solution do not actually merge cells, but create such visual effect.You may try this. Demo uses two DataGrid controls. The row height of first DataGrid is increased to create merged cell effect.
注意:这个解决方案实际上并没有合并单元格,而是创建了这样的视觉效果。你可以试试这个。演示使用两个 DataGrid 控件。增加第一个 DataGrid 的行高以创建合并单元格效果。
Alternative :ReoGridis MS Excel compatible control which supports merge/unmergecells feature like Excel. ReoGrid claims to be free and open source. It do not support Data Binding but it has support for DataTable.
替代方案:ReoGrid是 MS Excel 兼容控件,它支持像 Excel 一样的合并/取消合并单元格功能。ReoGrid 声称是免费和开源的。它不支持 Data Binding 但它支持 DataTable。


