Reputation: 21
I've come across a problem related to grouping in the WPF Data Grid where the right hand side margin does not match the left hand side when using an expander control. This issue is more obvious when adding extra margin to the expander.
My intention is to have each group as an expander but with a margin either side, so as more groups are added, the grid columns become "squeezed" more into the centre. This appears to happen on the left hand side, but not the right hand side.
All of my columns are "auto" apart from one which is set to * so that the grid column always stretches to fit the window. In doing this, the grid seems to have trouble creating the extra space required on the right hand side to fit the entire column set. The left hand side seems fine as it appears to expand the row selector every time a new group is created, pushing the grid columns further to the right.
This is how it currently looks: http://oi58.tinypic.com/117cojb.jpg
This is how i want it to look when adding a new group each time: http://oi62.tinypic.com/2rcn20w.jpg
In the second picture, I had to manually drag the column widths to get the expander to fit "on screen". Ideally i want this to be handled automatically for each new group which is added.
The Window Xaml...
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="1000"
Height="600">
<Window.Resources>
<!-- Data Grid -->
<Style TargetType="{x:Type DataGrid}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="RowBackground" Value="Transparent" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="GridLinesVisibility" Value="None" />
<Setter Property="SelectionMode" Value="Extended" />
<Setter Property="SelectionUnit" Value="FullRow" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
<Setter Property="RowHeaderWidth" Value="0" />
</Style>
<!-- Group Style -->
<Style x:Key="DefaultGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Header="{Binding Name}"
Margin="10"
IsExpanded="True"
>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Expander -->
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Border Background="LightCoral" CornerRadius="3" Opacity="0.5" />
<DockPanel>
<StackPanel
DockPanel.Dock="Top"
Orientation="Horizontal">
<ToggleButton Width="20" Content=">" Margin="5" VerticalAlignment="Center"
IsChecked="{Binding Path=IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"
/>
<ContentPresenter VerticalAlignment="Center"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
DockPanel.Dock="Top"
Focusable="false" />
</StackPanel>
<ContentPresenter x:Name="ExpanderContent"
DockPanel.Dock="Bottom"
Visibility="Collapsed" />
</DockPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ExpanderContent" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DataGrid x:Name="IssuesGrid"
Margin="20"
ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTextColumn Width="Auto"
Binding="{Binding ID}"
CanUserSort="False"
Header="ID" />
<DataGridTextColumn Width="Auto"
Binding="{Binding Customer}"
CanUserSort="False"
Header="Customer" />
<DataGridTextColumn Width="*"
Binding="{Binding Title}"
CanUserSort="False"
Header="Title" />
<DataGridTextColumn Width="Auto"
Binding="{Binding AssignedTo}"
CanUserSort="False"
Header="Assigned To" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource DefaultGroupStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button x:Name="btnGroup1"
Width="Auto"
Margin="5"
Content="Add Group" />
</StackPanel>
</Grid>
</Window>
The Code Behind...
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Public Class MainWindow
Public Items As New IssueCollection
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer A", .Title = "A long title to take up a good amount of space"})
Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer A", .Title = "A long title to take up a good amount of space"})
Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})
Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})
Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})
IssuesGrid.ItemsSource = CollectionViewSource.GetDefaultView(Items)
End Sub
Private Sub btnGroup1_Click(sender As Object, e As RoutedEventArgs) Handles btnGroup1.Click
CType(IssuesGrid.ItemsSource, ICollectionView).GroupDescriptions.Add(New PropertyGroupDescription("Customer"))
End Sub
End Class
Public Class Issue
Public Property ID As String
Public Property AssignedTo As String
Public Property Customer As String
Public Property Title As String
End Class
Public Class IssueCollection
Inherits ObservableCollection(Of Issue)
Implements INotifyPropertyChanged
Public Sub New()
End Sub
End Class
Any ideas on how i can get around this problem?- I've tried altering the margin and padding on all levels (i.e. columns, row presenter and expander) with no luck.
Thank you.
Upvotes: 2
Views: 2574
Reputation: 13679
I made little adjustment to group style
<!-- Group Style -->
<Style x:Key="DefaultGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Grid Width="{Binding ActualWidth,RelativeSource={RelativeSource TemplatedParent}}">
<Expander Header="{Binding Name}" Margin="10" IsExpanded="True">
<ItemsPresenter />
</Expander>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I enclosed the expander in a grid and binded it's width to the container's width, which will eventually restrict the child to grow larger
however this approach has a limitation i.e. this will not re-position the grid columns so may have some artifects, I think that can be handled separately
result
Upvotes: 1