Search code examples
c#wpfmvvmdatagrid

Set Text Wrapping for an AutoGenerated DataGrid TextBox using a behavior


I am attempting to set an auto-generated DataGrid column's TextBox to wrap text using a behavior. However, setting the property during the AutoGeneratingColumn event does not work. Am I setting the correct property or is there some problem?

Here is the XAML for the DataGrid:

<DataGrid x:Name="TableGrid" ItemsSource="{Binding GridData}" AutoGenerateColumns="True">
   <i:Interaction.Behaviors>
      <b:AutoHeaderBehavior/>
   </i:Interaction.Behaviors>
</DataGrid>

And here is the code for the behavior:

public class AutoHeaderBehavior : Behavior<DataGrid>
{
   protected override void OnAttached()
   {
      base.OnAttached();
      this.AssociatedObject.AutoGeneratingColumn += OnGeneratingColumn;
   }

   protected override void OnDetaching()
   {
      this.AssociatedObject.AutoGeneratingColumn -= OnGeneratingColumn;
      base.OnDetaching();
   }

   private void OnGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
   {
      if (e.PropertyDescriptor is PropertyDescriptor descriptor)
      {
         e.Column.Header = descriptor.DisplayName ?? descriptor.Name;
         if (descriptor.DisplayName == "Description")
         {
            var wrapping = new Setter() { Property = TextBox.TextWrappingProperty, Value = TextWrapping.Wrap };
            var style = new Style(typeof(TextBox));
            style.Setters.Add(wrapping);
            (e.Column as DataGridTextColumn).ElementStyle = style;
            e.Column.Width = 300;
         }
      }
      else
         e.Cancel = true;
   }
}

Solution

  • Well, after fiddling around with this problem for several hours I decided to resolve the issue by replacing the column entirely.

    private void OnGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.PropertyDescriptor is PropertyDescriptor descriptor)
        {
            e.Column.Header = descriptor.DisplayName ?? descriptor.Name;
            if (descriptor.DisplayName == "Description")
            {
                var column = new DataGridTemplateColumn();
                var element = new FrameworkElementFactory(typeof(TextBlock));
                var binding = new Binding("Description");
                var template = new DataTemplate();
    
                element.SetBinding(TextBlock.TextProperty, binding);
                element.SetValue(TextBox.TextWrappingProperty, TextWrapping.Wrap);
                template.VisualTree = element;
                template.Seal();
                column.CellTemplate = template;
                column.Header = e.Column.Header;
                column.Width = 300;
                    
                e.Column = column;
            }
        }
        else
            e.Cancel = true;
    }