I have the following DataGrid
in WPF with two groups.
First group is a bool flag which represents if a person is active/inactive.
The second group (or sub-group) is the ID of each person.
Each person can have multiple cities, therefore the grouping for the ID, because each person is shown multiple in the DataGrid
.
Here is the XAML:
<DataGrid CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding DataSource}">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<DataTrigger Binding="{Binding Name}" Value="True">
<Setter Property="Background" Value="{StaticResource ActiveBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Name}" Value="False">
<Setter Property="Background" Value="{StaticResource InactiveBrush}"/>
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name, Converter={StaticResource BoolToTextConverter}}" Margin="5 2 5 2"/>
<TextBlock Text=":" Margin="0 2 5 2"/>
<TextBlock Text="{Binding ItemCount}" Margin="0 2 0 2"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="LightSteelBlue">
<TextBlock Text="{Binding Name}" Foreground="White" Margin="5 2 5 2"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<DockPanel>
<Button BorderThickness="0" Content="Edit" Margin="3"
Command="{Binding Commands.Edit}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</DockPanel>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" IsReadOnly="True"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
<DataGridTextColumn Header="City" Binding="{Binding City}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
It all works fine! However, I don't like the blue row for each sub-group. What I want to achieve is the grouping style in the following image:
For each sub-group I want the Edit button and the ID to appear only once per person. How would I do this? Is it possible in XAML only or should I remove the reduntant content in code-behind?
Edit
Here some test data:
public class Person
{
public Person(bool active, int id, string name, string city)
{
Active = active;
ID = id;
Name = name;
City = city;
}
public bool Active { get; set; }
public int ID { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
var data = new ObservableCollection<Person>
{
new Person(true, 233, "Max", "New York"),
new Person(true, 233, "Max", "Los Angeles"),
new Person(true, 314, "John", "Paris"),
new Person(true, 578, "Mary", "Vienna"),
new Person(true, 782, "Susan", "Rome"),
new Person(true, 782, "Susan", "Prague"),
new Person(true, 782, "Susan", "San Francisco"),
new Person(false, 151, "Henry", "Chicago")
};
DataSource = new ListCollectionView(data);
}
private ListCollectionView _dataSource;
public ListCollectionView DataSource
{
get { return _dataSource; }
set
{
_dataSource = value;
_dataSource.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
_dataSource.GroupDescriptions.Add(new PropertyGroupDescription("ID"));
}
}