我有一个填充数据的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.
有没有办法实现这个目标?谢谢。
答案 0 :(得分:2)
我终于找到了实现我想要做的事情的方法:
我使用从DataTemplateSelector派生的Selector设置DataGrid.ItemTemplateSelector属性。在这个选择器的SelectTemplate()方法中,我为正常行返回null(以应用默认模板),否则我创建并返回对应于特殊行的DataTemplate(动态地,感谢XamlReader)。此模板由DataGrid组成。 DataGrid的ItemsSource属性使用转换器设置(行数据转换为对象列表)。
答案 1 :(得分:1)
我设法创建了以下内容:
如果我理解正确,在这种情况下,您必须使用嵌套的DataGrid
。这种效果可以通过DataGridTemplateColumn.CellTemplate -> your DataTemplate
来实现。此外,模式应该是“正常”TextBlock
,因此当嵌套DataGrid
隐藏时它会显示一些值。我们将使用DataTrigger
中的DataTemplate
进行检查。
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;
}
}
DataGrid的两个ObservableCollection
:
private ObservableCollection<Person> DataForDataGrid = new ObservableCollection<Person>();
private ObservableCollection<Person> DataForInsertedDataGrid = new ObservableCollection<Person>();
主DataGrid的处理程序Loaded
事件集数据:
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;
}
NestedDataGrid的 Loaded
事件处理程序:
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
的列总数。