【问题标题】:Merge Cells in WPF DataGrid合并 WPF DataGrid 中的单元格
【发布时间】:2013-06-16 15:29:52
【问题描述】:

我想创建一个跨越一列中多行的 WPF 数据网格。像这样:

+-------+----------------+
| Name  | Attributes     |
+-------+----------------+
|       | Horse Power    |
| BMW   +----------------+
|       | Color          |
+-------+----------------+
|       | Weight         |
| Ford  +----------------+
|       | Color          |
+-------+----------------+

如何更改以下代码以完成它?

<DataGrid AutoGenerateColumns="False">
     <DataGrid.Columns>
          <DataGridTextColumn Header="Name" />
          <DataGridTextColumn Header="Attributes" />
     </DataGrid.Columns>
</DataGrid>

【问题讨论】:

  • 您是否有理由为此使用DataGrid?这看起来很简单,您应该可以使用自定义的 ListViewItems 在ListView 中更轻松地完成它。
  • 我认为 ListView 也可以。真实的东西有更多的列,它们会在点击特定单元格时被着色等等......
  • 我自己不是ListView 的最大粉丝,但对于您正在寻找的自定义,我认为这将是更可取的选择。我发现 DataGrid(甚至是第 3 方 DataGrid 控件)不容易执行“多行列单元格”之类的操作。

标签: c# wpf datagrid


【解决方案1】:

我设法实现了一个解决方案,该解决方案通过三个级别的分组来满足您的需求,但有一个小问题,即组标题随数据水平滚动。

    <Style x:Key="GroupItemStyle" TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                        <StackPanel Orientation="Horizontal" >
                            <Border BorderThickness="0">
                                <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>

                                    <Border BorderThickness="1" MinWidth="150">
                                        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                                            <ContentPresenter Content="{Binding Name}" >
                                            </ContentPresenter>
                                        </Grid>

                                    </Border>
                                    <Border BorderThickness="0" Grid.Column="1">
                                        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                                            <ItemsPresenter/>
                                        </Grid>
                                    </Border>
                                </Grid>
                            </Border>
                        </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

还有网格:

            <DataGrid ItemsSource="{Binding GroupedData}" AutoGenerateColumns="False" MinRowHeight="25" CanUserAddRows="False" CanUserDeleteRows="False">
                <DataGrid.GroupStyle>
                    <!-- First Group -->
                    <GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <DataGridRowsPresenter/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>

                    <!-- Second Group -->
                    <GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <DataGridRowsPresenter/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>

                    </GroupStyle>

                    <!-- Third Group -->
                    <GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <DataGridRowsPresenter/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </DataGrid.GroupStyle>
                <DataGrid.Columns>
        ...
                </DataGrid.Columns>
            </DataGrid>

【讨论】:

    【解决方案2】:

    关于这个主题的另一篇有用的文章是http://www.mindstick.com/Articles/90371ed3-c0f7-49eb-ba2d-9d1f2c9b14e2/?Grid%20Control%20in%20WPF

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Button x:Name="btn1" Content="First Button" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
        <Button x:Name="btn2" Content="Second Button" Grid.Row="0" Grid.Column="2" />
        <Button x:Name="btn3" Content="Thired Button" Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" />
        <Button x:Name="btn4" Content="Fourth Button" Grid.Row="1" Grid.Column="1" />
        <Button x:Name="btn5" Content="Fifth Button" Grid.Row="1" Grid.Column="2" />
        <Button x:Name="btn6" Content="Six Button" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" />
    

    注意Grid.ColumnSpanGrid.RowSpan 属性。

    【讨论】:

    • 这似乎是关于布局网格,而不是 DataGrid
    【解决方案3】:

    尝试使用DataGridTemplateColumn。我为数据绑定创建了示例测试类

    public class Test
    {
    
        public Test(string name, string attribute1, string attribute2)
        {
            Name = name;
            Attributes = new Attribute(attribute1, attribute2);
        }
    
        public string Name { get; set; }
        public Attribute Attributes { get; set; }
    }
    
    public class Attribute
    {
    
        public Attribute(string attribute1, string attribute2)
        {
            Attribute1 = attribute1;
            Attribute2 = attribute2;
        }
    
        public string Attribute1 { get; set; }
        public string Attribute2 { get; set; }
    }
    

    还有一个 xaml 中的数据网格

    <DataGrid AutoGenerateColumns="False"  Name="dataGrid1" ItemsSource="{Binding}">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Name"  >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBlock Text="{Binding Path=Name}"  VerticalAlignment="Center" Margin="3,3,3,3"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Attributes"  >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate >
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="50*"/>
                                    <RowDefinition />
                                    <RowDefinition Height="50*"/>
                                </Grid.RowDefinitions>
                                <TextBlock Grid.Row="0" Text="{Binding Path=Attributes.Attribute1}" VerticalAlignment="Center" Margin="3,3,3,3"/>
                                <Line Grid.Row="1" Stroke="Black" Stretch="Fill" X2="1" VerticalAlignment="Center"/>
                                <TextBlock Grid.Row="2" Text="{Binding Path=Attributes.Attribute2}"  VerticalAlignment="Center" Margin="3,3,3,3"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    

    并在代码隐藏中填写

    List<Test> list = new List<Test>();
    //populate list with your data here
    dataGrid1.DataContext = list;
    

    【讨论】:

    • 这可行,但请注意,一旦您使用 DataGridTemplateColumn,复制/粘贴将不再适用于跨行或跨列。
    • 如果属性的数量是动态的,有时是 2,有时是 4 怎么办?怎么渲染?
    猜你喜欢
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多