垂直合并WPF DataGrid中的单元格

时间:2016-09-28 12:50:33

标签: c# wpf datagrid

我想在WPF中创建一个DataGrid,其中一些单元格将"合并在一起",如果它们是相似的。

示例:

+---------+------+-----+
| Country | Name | Age |
+---------+------+-----+
|         | Lisa | 24  |
+         +------+-----+
| Danmark |  Per | 32  |
+         +------+-----+
|         | Hans | 33  |
+---------+------+-----+
| Germany | Mick | 22  |
+---------+------+-----+

有没有办法使用DataGrid使用绑定来实现这个目的?

提前多多感谢。

2 个答案:

答案 0 :(得分:1)

抱歉,与其他东西混在一起。

欺骗这种情况是使用Groups中形成的CollectionViewSource作为ItemsSource的{​​{1}}。并且,使用DataGrid本身作为DataGrid的{​​{1}}。

<强> 的Xaml

CellTemplate

Column

    <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>

这应该让你开始。

输出:

Vertical Grid Output

答案 1 :(得分:0)

我在github.com上创建了一个演示项目      输出:

enter image description here

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兼容控件,支持Excel等merge/unmerge单元格功能。 ReoGrid声称是免费和开源的。它不支持数据绑定,但它有support for DataTable