【问题标题】:DataGrid with multiple headers具有多个标题的 DataGrid
【发布时间】:2013-06-22 06:20:15
【问题描述】:

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

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)

Here is a screen shot illustrating my needs.

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

【问题讨论】:

  • 是否总是 row(3) 第三行应该有标题和数据?
  • 不,可以是任意行。

标签: wpf templates datagrid header row


【解决方案1】:

我终于找到了实现我想要做的事情的方法:

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

【讨论】:

    【解决方案2】:

    我已经设法创建了以下内容:

    如果我理解正确,在这种情况下,您必须使用嵌套的DataGrid。这个效果可以通过DataGridTemplateColumn.CellTemplate -> your 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>
    

    Person类列表:

    public class Person
    {
        public string Name
        {
           get;
           set;
        }
    
        public int Age
        {
           get;
           set;
        }
    
        // For clarity using string. 
        // In real project using a bool.
        public string ShowInsertedGrid
        {
           get;
           set;
        }
    }
    

    两个 ObservableCollection 用于 DataGrid:

    private ObservableCollection<Person> DataForDataGrid = new ObservableCollection<Person>();
    private ObservableCollection<Person> DataForInsertedDataGrid = new ObservableCollection<Person>();
    

    在处理程序 Loaded 主 DataGrid 的事件集数据中:

        private void SimpleDataGrid_Loaded(object sender, RoutedEventArgs e)
        {
            DataForDataGrid.Add(new Person()
            {                
                Age = 2,
                Name = "Nick",
                ShowInsertedGrid = "Hidden", // Hidden NestedDataGrid
            });
    
            DataForDataGrid.Add(new Person()
            {
                Age = 1,
                Name = "Sam",
            });
    
            DataForDataGrid.Add(new Person()
            {
                Name = "Kate",
                Age = 15,
                ShowInsertedGrid = "Hidden",  // Hidden NestedDataGrid
            });
    
            SimpleDataGrid.ItemsSource = DataForDataGrid;            
        }
    

    Loaded NestedDataGrid 的事件处理程序:

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

    为了美丽和改善外观,请使用Styles

    编辑:

    如果您希望您的嵌套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>
    

    InsertedDataGrid2_Loaded你在哪里设置数据:

        private void InsertedDataGrid2_Loaded(object sender, RoutedEventArgs e)
        {
            DataGrid MyDataGrid = sender as DataGrid;
    
            DataForInsertedDataGrid2.Add(new Person()
            {
                Name = "Bob2",
                Age = 215,
            });
    
            DataForInsertedDataGrid2.Add(new Person()
            {
                Name = "SpanchBob2",
                Age = 251,
            });
    
            MyDataGrid.ItemsSource = DataForInsertedDataGrid2;
        }
    

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

    【讨论】:

    • 非常感谢您的回答。这几乎正​​是我想要实现的目标。唯一的事情是您在单个单元格中添加嵌套的 DataGrid,而我需要在整行中添加嵌套的 DataGrid。
    • 感谢您的编辑,但确实这肯定不是最好的解决方案,也不是我需要的行为。还是谢谢!
    猜你喜欢
    • 1970-01-01
    • 2014-10-05
    • 2018-12-26
    • 2015-01-02
    • 2015-01-26
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    相关资源
    最近更新 更多