I am working on an WPF MVVM application. I have a DataGrid, which is binded to a DataTable. AutoGenerateColumns
is set to true.
However, I want to wrap the text of a column to 2 or 3 lines if needed. Currently, when I scroll the DataGrid, when the first column's text is longer, the first column expands as much as it needs and the last column is not seen anymore or is cut.
Here is the code:
<Grid.Resources>
<Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="ItemsControl.MinHeight" Value="50" />
<Setter Property="ItemsControl.MinWidth" Value="60" />
<Setter Property="ItemsControl.HorizontalContentAlignment" Value="Center" />
<Setter Property="ItemsControl.VerticalContentAlignment" Value="Center" />
</Style>
</Grid.Resources>
Grid:
<Grid
Width="800"
Height="500"
Visibility="Visible">
<Grid.Resources>
//code
</Grid.Resources>
<DataGrid
Name="Map"
Width="Auto"
Height="Auto"
Margin="0,10,0,0"
AutoGenerateColumns="True"
AutoGeneratingColumn="Map_AutoGeneratingColumn"
CanUserAddRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="True"
CanUserSortColumns="False"
ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"
FontStretch="Normal"
IsReadOnly="True"
ItemsSource="{Binding MapDataTable}" />
I omitted things that are not relevant to the question.
Here is what I have tried:
Attempt 1:
<Grid.Resources>
<Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="ItemsControl.MinHeight" Value="50" />
<Setter Property="ItemsControl.MinWidth" Value="60" />
<Setter Property="ItemsControl.HorizontalContentAlignment" Value="Center" />
<Setter Property="ItemsControl.VerticalContentAlignment" Value="Center" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
Attempt 2:
<Grid.Resources>
<Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="ItemsControl.MinHeight" Value="50" />
<Setter Property="ItemsControl.MinWidth" Value="60" />
<Setter Property="ItemsControl.HorizontalContentAlignment" Value="Center" />
<Setter Property="ItemsControl.VerticalContentAlignment" Value="Center" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</Grid.Resources>
Both of them don't work. What is the correct way to fix the text wrapping? AutoGenerateColumns
MUST be true.
CodePudding user response:
As you have realized modifying the column header does not modify the column. The solution is to listen to the DataGrid.AutoGeneratingColumn
event and modify the generated columns selectively.
I see that you are already listening to the AutoGeneratingColumn
event. You simply have to modify the event handler to apply a TextBlock
style to the text columns.
First define a Style
that targets TextBlock
and enables text wrapping:
<DataGrid AutoGeneratingColumn="Map_AutoGeneratingColumn">
<DataGrid.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGrid.Resources>
</DataGrid>
Then go to the AutogeneratingColumn
event handler Map_AutoGeneratingColumn
and filter the text columns to set their initial width and to apply the previously defined TextBlock
style:
private void Map_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var dataGrid = sender as DataGrid;
if (e.Column is DataGridTextColumn textColumn)
{
textColumn.ElementStyle = dataGrid.FindResource(typeof(TextBlock)) as Style;
e.Column.Width = 100;
}
}