2
votes

Basically what I'm trying to achieve is to have only the second column of my DataGrid to enable text wrapping instead of cutting it when there's no more space.

My problem is that the DataGrid is empty in the xaml code and I generate it from a class programmatically.

Xaml of the DataGrid is this:

<DockPanel Grid.Row="1">
    <DataGrid Name="dg_Misc" Margin="2" Background="#FF212121" SelectionUnit="Cell" VerticalGridLinesBrush="Black" GridLinesVisibility="Vertical"/>
</DockPanel>

While the c# with which I generate the DataGrid is this:

Oggetto oggetto = new Oggetto();
Oggetti.Add( new Oggetto() { } );

dg_Misc.ItemsSource = Oggetti;
dg_Misc.Items.Refresh();

In the class Oggetto I have two strings, Name and Description and they become two headers for the columns when the DataGrid is generated, I want the cells of the column Description to enable text wrapping.

2

2 Answers

4
votes

Make use of the AutoGeneratingColumn event.

In XAML, hook up the event with an event handler:

<DataGrid Name="dg_Misc" Margin="2" 
          Background="#FF212121" 
          SelectionUnit="Cell" 
          VerticalGridLinesBrush="Black" 
          GridLinesVisibility="Vertical"
          AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"/>

And in code behind implement your event handler like this:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.Column.Header.ToString() == "Description")
    {
        var col = e.Column as DataGridTextColumn;

        var style = new Style(typeof(TextBlock));
        style.Setters.Add(new Setter(TextBlock.TextWrappingProperty, TextWrapping.Wrap));
        style.Setters.Add(new Setter(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center));

        col.ElementStyle = style;
    }
}

I also added a VerticalAlignment of center so it looks better. Feel free to comment/remove that line.

2
votes

You should define the columns of the DataGrid yourself.

<DataGrid Name="dg_Misc" Margin="2" Background="#FF212121" SelectionUnit="Cell" VerticalGridLinesBrush="Black" GridLinesVisibility="Vertical"
          AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />

        <DataGridTemplateColumn Header="Description">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="{x:Type local:Oggetto}">
                    <TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

I added AutoGenerateColumns="False", so we don't end up with four columns, only the columns I defined above.

Then I defined the two columns.

  1. First is a simple DataGridTextColumn with the Binding set to the Name property.

  2. The second one is a DataGridTemplateColumn where I can define the template of the column myself. I've put a TextBlock in it with its Binding set to Desciription and TextWrapping="Wrap" to actually achieve want you wanted.