In our application we use datagrids to layout rows filled with templated content and buttons, however a problem occurs intermittently where some of the columns will size themselves sometimes to the minimum width of the column and sometimes to the column header content width. This seems to be something related to the time at which the itemssource is set and when the loading event occurs but I can't pin it down for sure.
Example of incorrect behaviour
Example of correct behaviour
The itemssource is bound to an ObservableCollection on the viewmodel which populates async using the async and await keywords and a dataservice.
I have attempted to fix the issue by hiding all columns on initialise and then once the itemssource is set and isloaded has been called setting all the columns back to the initial visibility, this seemed to have some affect but did not fix the problem completely.
The xaml for the column definitions
<Style x:Key="MainDataGridColumnHeader" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<TextBlock Text="{TemplateBinding Content}" Foreground="{StaticResource HighlightedTextBrush}"
Background="Transparent"
FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MainDataGridRow" TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="{StaticResource LightBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource Faded10MidBackgroundBrush}"/>
<Setter Property="BorderThickness" Value="0,0,0,1" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Padding" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="0"
Margin="0,5"
Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}">
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MainDataGridCell" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{StaticResource TextBrush}"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
The xaml for column header, row and cell styles
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="dateColumn" Header="Race Time" MinWidth="110" Width="Auto" CellTemplate="{StaticResource RacesRaceTimeTemplate}" />
<DataGridTemplateColumn x:Name="iconColumn" Width="62" CellTemplate="{StaticResource RacesRaceIconTemplate}"/>
<DataGridTemplateColumn x:Name="nameColumn" Width="*" CellTemplate="{StaticResource RacesRaceDescriptionTemplate}"/>
<DataGridTemplateColumn x:Name="favsColumn" Width="auto" Header="Fav / 2nd Fav" CellTemplate="{StaticResource RacesFavSelectionsTemplate}" />
<DataGridTemplateColumn x:Name="additionalColumn" Width="78" CellTemplate="{StaticResource RacesAdditionalOptionsTemplate}" />
</DataGrid.Columns>
For now I can mostly resolve the problem by setting hardcoded widths for the columns, but that is not a reasonable solution going forward as we will have variable width content.
Does anyone have a solution for this problem?
Did you try setting the min width of all columns, then specify the width based on percentage
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="dateColumn" MinWidth="110" Width="*" Header="Race Time" CellTemplate="{StaticResource RacesRaceTimeTemplate}" />
<DataGridTemplateColumn x:Name="iconColumn" MinWidth="62" Width="2*" CellTemplate="{StaticResource RacesRaceIconTemplate}"/>
<DataGridTemplateColumn x:Name="nameColumn" MinWidth="500" Width="3*" CellTemplate="{StaticResource RacesRaceDescriptionTemplate}"/>
<DataGridTemplateColumn x:Name="favsColumn" MinWidth="232" Width="3*" Header="Fav / 2nd Fav" CellTemplate="{StaticResource RacesFavSelectionsTemplate}" />
<DataGridTemplateColumn x:Name="additionalColumn" MinWidth="78" Width="*" CellTemplate="{StaticResource RacesAdditionalOptionsTemplate}" />
</DataGrid.Columns>
you may see this answer.
try to update your width columns programmatically after setting your ItemsSource
foreach (DataGridColumn c in dg.Columns)
c.Width = 0;
// Update your DG's source here
foreach (DataGridColumn c in dg.Columns)
c.Width = DataGridLength.Auto;
and then UpdateLayout your DataGrid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With