Wpf 具有多个标头的DataGrid

Wpf 具有多个标头的DataGrid,wpf,templates,datagrid,header,row,Wpf,Templates,Datagrid,Header,Row,我有一个充满数据的数据网格。我想做的是修改特定行的模板,以便同时显示行和新标题。例如: Header 1 | Header 2 | Header 3 Data 1 | Data 2 | Data 3 (row 1) Data 1 | Data 2 | Data 3 (row 2) Header 1 | Header 2 | Header 3 | Head

我有一个充满数据的数据网格。我想做的是修改特定行的模板,以便同时显示行和新标题。例如:

Header 1 | Header 2 | Header 3
Data   1 | Data   2 | Data   3                               (row 1)
Data   1 | Data   2 | Data   3                               (row 2)
Header 1 | Header 2 | Header 3 | Header 4 | Header 5         (row 3)
Data   1 | Data   2 | Data   3 | Data   4 | Data   5         (row 3)
Data   1 | Data   2 | Data   3                               (row 4)


有没有办法做到这一点?谢谢。

我已成功创建了以下内容:

如果我理解正确,在这种情况下,您必须使用嵌套的
DataGrid
。这种效果可以通过
DataGridTemplateColumn.CellTemplate->DataTemplate
实现。此外,模式应该是“正常的”
TextBlock
,因此当嵌套
DataGrid
隐藏时,它会显示一些值。将使用
DataTemplate
中的
DataTrigger
执行检查

XAML代码:

    <DataGrid Name="SimpleDataGrid" AutoGenerateColumns="False" RowHeaderWidth="0" CanUserAddRows="False" CanUserResizeColumns="False" CanUserResizeRows="False" Loaded="SimpleDataGrid_Loaded">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="1.5*" Header="HeaderWithDataGrid" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <!-- Nested DataGrid -->
                            <DataGrid Name="InsertedDataGrid" AutoGenerateColumns="False" RowHeaderWidth="0" Loaded="InsertedDataGrid_Loaded">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="InsertedHeader1" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader2" Width="1.5*" Binding="{Binding Age}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader3" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                </DataGrid.Columns>
                            </DataGrid>

                            <!-- Simply value, if nested DataGrid will be Hidden -->
                            <TextBlock Name="SimpleValue" Text="{Binding Age}" Visibility="Hidden" />
                        </Grid>

                        <DataTemplate.Triggers>
                            <!-- It checks for Hidden NestedDataGrid -->
                            <DataTrigger Binding="{Binding ShowInsertedGrid}" Value="Hidden">
                                <Setter TargetName="InsertedDataGrid" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="SimpleValue" Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <!-- Simply column -->
            <DataGridTextColumn Header="SimpleHeader" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
        </DataGrid.Columns>
    </DataGrid>
DataGrid的两个
ObservableCollection

private ObservableCollection<Person> DataForDataGrid = new ObservableCollection<Person>();
private ObservableCollection<Person> DataForInsertedDataGrid = new ObservableCollection<Person>();
已加载嵌套数据网格的事件处理程序

    private void InsertedDataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        DataGrid MyDataGrid = sender as DataGrid;

        DataForInsertedDataGrid.Add(new Person()
        {
            Name = "Bob",
            Age = 15,
        });

        DataForInsertedDataGrid.Add(new Person()
        {
            Name = "SpanchBob",
            Age = 151,
        });

        MyDataGrid.ItemsSource = DataForInsertedDataGrid;
    }
为了美观和使用
样式改善外观

编辑:

如果您希望嵌套的
DataGrid
位于整行,那么我可以建议以下解决方案(不是说它是最佳解决方案,但我只能提供此解决方案):

对于每个单元格,将使用DataTemplate。因此,
SimpleHeader
转化为:

            <DataGridTemplateColumn Width="1.5*" Header="SimpleHeader" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <!-- Nested DataGrid -->
                            <DataGrid Name="InsertedDataGrid2" AutoGenerateColumns="False" RowHeaderWidth="0" Loaded="InsertedDataGrid2_Loaded">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="InsertedHeader4" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader5" Width="1.5*" Binding="{Binding Age}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader6" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                </DataGrid.Columns>
                            </DataGrid>

                            <!-- Simply value, if nested DataGrid will be Hidden -->
                            <TextBlock Name="SimpleValue" Text="{Binding Name}" Visibility="Hidden" />
                        </Grid>

                        <DataTemplate.Triggers>
                            <!-- It checks for Hidden NestedDataGrid -->
                            <DataTrigger Binding="{Binding ShowInsertedGrid}" Value="Hidden">
                                <Setter TargetName="InsertedDataGrid2" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="SimpleValue" Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

对于使用
DataGrid
的每一列,以及为其加载数据的代码。因此,计算主数据网格和嵌套数据网格的总列数,我已经创建了以下内容:

如果我理解正确,在这种情况下,您必须使用嵌套的
DataGrid
。这种效果可以通过
DataGridTemplateColumn.CellTemplate->DataTemplate
实现。此外,模式应该是“正常的”
TextBlock
,因此当嵌套
DataGrid
隐藏时,它会显示一些值。将使用
DataTemplate
中的
DataTrigger
执行检查

XAML代码:

    <DataGrid Name="SimpleDataGrid" AutoGenerateColumns="False" RowHeaderWidth="0" CanUserAddRows="False" CanUserResizeColumns="False" CanUserResizeRows="False" Loaded="SimpleDataGrid_Loaded">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="1.5*" Header="HeaderWithDataGrid" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <!-- Nested DataGrid -->
                            <DataGrid Name="InsertedDataGrid" AutoGenerateColumns="False" RowHeaderWidth="0" Loaded="InsertedDataGrid_Loaded">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="InsertedHeader1" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader2" Width="1.5*" Binding="{Binding Age}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader3" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                </DataGrid.Columns>
                            </DataGrid>

                            <!-- Simply value, if nested DataGrid will be Hidden -->
                            <TextBlock Name="SimpleValue" Text="{Binding Age}" Visibility="Hidden" />
                        </Grid>

                        <DataTemplate.Triggers>
                            <!-- It checks for Hidden NestedDataGrid -->
                            <DataTrigger Binding="{Binding ShowInsertedGrid}" Value="Hidden">
                                <Setter TargetName="InsertedDataGrid" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="SimpleValue" Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <!-- Simply column -->
            <DataGridTextColumn Header="SimpleHeader" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
        </DataGrid.Columns>
    </DataGrid>
DataGrid的两个
ObservableCollection

private ObservableCollection<Person> DataForDataGrid = new ObservableCollection<Person>();
private ObservableCollection<Person> DataForInsertedDataGrid = new ObservableCollection<Person>();
已加载嵌套数据网格的事件处理程序

    private void InsertedDataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        DataGrid MyDataGrid = sender as DataGrid;

        DataForInsertedDataGrid.Add(new Person()
        {
            Name = "Bob",
            Age = 15,
        });

        DataForInsertedDataGrid.Add(new Person()
        {
            Name = "SpanchBob",
            Age = 151,
        });

        MyDataGrid.ItemsSource = DataForInsertedDataGrid;
    }
为了美观和使用
样式改善外观

编辑:

如果您希望嵌套的
DataGrid
位于整行,那么我可以建议以下解决方案(不是说它是最佳解决方案,但我只能提供此解决方案):

对于每个单元格,将使用DataTemplate。因此,
SimpleHeader
转化为:

            <DataGridTemplateColumn Width="1.5*" Header="SimpleHeader" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <!-- Nested DataGrid -->
                            <DataGrid Name="InsertedDataGrid2" AutoGenerateColumns="False" RowHeaderWidth="0" Loaded="InsertedDataGrid2_Loaded">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="InsertedHeader4" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader5" Width="1.5*" Binding="{Binding Age}" IsReadOnly="False" />
                                    <DataGridTextColumn Header="InsertedHeader6" Width="1.5*" Binding="{Binding Name}" IsReadOnly="False" />
                                </DataGrid.Columns>
                            </DataGrid>

                            <!-- Simply value, if nested DataGrid will be Hidden -->
                            <TextBlock Name="SimpleValue" Text="{Binding Name}" Visibility="Hidden" />
                        </Grid>

                        <DataTemplate.Triggers>
                            <!-- It checks for Hidden NestedDataGrid -->
                            <DataTrigger Binding="{Binding ShowInsertedGrid}" Value="Hidden">
                                <Setter TargetName="InsertedDataGrid2" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="SimpleValue" Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

对于使用
DataGrid
的每一列,以及为其加载数据的代码。因此,计算主数据网格和嵌套数据网格的总列数。
DataGrid

我终于找到了一种方法来实现我的目标:


我使用从DataTemplateSelector派生的选择器设置DataGrid.ItemTemplateSelector属性。在这个选择器的SelectTemplate()方法中,我为普通行返回null(以应用默认模板),否则我创建并返回与特殊行对应的DataTemplate(动态地,感谢XamlReader)。此模板由DataGrid组成。DataGrid的ItemsSource属性是使用转换器(将行数据转换为对象列表)设置的。

我终于找到了一种方法来实现我的目标:


我使用从DataTemplateSelector派生的选择器设置DataGrid.ItemTemplateSelector属性。在这个选择器的SelectTemplate()方法中,我为普通行返回null(以应用默认模板),否则我创建并返回与特殊行对应的DataTemplate(动态地,感谢XamlReader)。此模板由DataGrid组成。DataGrid的ItemsSource属性是使用转换器(将行数据转换为对象列表)设置的。

是否总是第(3)行中应该有标题和数据?否,它可以是任何行。是否总是第(3)行中应该有标题和数据?否,它可以是任何行。非常感谢您的回答。这几乎正是我想要实现的。唯一的问题是,您在单个单元格中添加嵌套的DataGrid,而我需要在整行中添加嵌套的DataGrid。感谢您的编辑,但实际上这肯定不是最好的解决方案,也不是我需要的行为。无论如何谢谢你!非常感谢你的回答。这几乎正是我想要实现的。唯一的问题是,您在单个单元格中添加嵌套的DataGrid,而我需要在整行中添加嵌套的DataGrid。感谢您的编辑,但实际上这肯定不是最好的解决方案,也不是我需要的行为。无论如何谢谢你!