C# 使用行为为自动生成的DataGrid文本框设置文本换行

C# 使用行为为自动生成的DataGrid文本框设置文本换行,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,我正在尝试将自动生成的DataGrid列的TextBox设置为使用行为包装文本。但是,在自动生成列事件期间设置属性不起作用。我是否设置了正确的属性,或者是否存在一些问题 以下是数据网格的XAML: <DataGrid x:Name="TableGrid" ItemsSource="{Binding GridData}" AutoGenerateColumns="True"> <i:Interaction.Beha

我正在尝试将自动生成的
DataGrid
列的
TextBox
设置为使用行为包装文本。但是,在
自动生成列
事件期间设置属性不起作用。我是否设置了正确的属性,或者是否存在一些问题

以下是数据网格的XAML:

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

下面是行为的代码:

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;
   }
}
公共类AutoHeaderBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.AutoGeneratingColumn+=OnGeneratingColumn;
}
附加时受保护的覆盖无效()
{
this.AssociatedObject.AutoGeneratingColumn-=OnGeneratingColumn;
base.OnDetaching();
}
生成列上的私有void(对象发送方,DataGridAutoGeneratingColumnEventArgs e)
{
if(例如,PropertyDescriptor是PropertyDescriptor描述符)
{
e、 Column.Header=descriptor.DisplayName??descriptor.Name;
if(descriptor.DisplayName==“Description”)
{
var wrapping=new Setter(){Property=TextBox.textwappingproperty,Value=textwapping.Wrap};
var style=新样式(typeof(TextBox));
样式。设置器。添加(包装);
(e.Column作为DataGridTextColumn);
e、 列宽=300;
}
}
其他的
e、 取消=真;
}
}

数据网格列有两种不同的模式,非编辑和编辑,用于:

  • 在非编辑模式下,它使用属性中的样式显示一个
    TextBlock
  • 在编辑模式下,它使用属性中的样式显示一个
    文本框
代码中的问题是将编辑样式应用于非编辑样式特性。我已经修改了您的行为代码,以编辑和非编辑模式包装文本。如果只希望在编辑模式下进行文本换行,只需删除
ElementStyle
属性和相应样式的指定

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

   protected override void OnDetaching()
   {
      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 textWrappingSetter = new Setter
            {
               Property = TextBox.TextWrappingProperty,
               Value = TextWrapping.Wrap
            };

            // Style for non-edit mode (TextBlock)
            var elementStyle = new Style(typeof(TextBlock));
            elementStyle.Setters.Add(textWrappingSetter);

            // Style for edit mode (TextBox)
            var editingElementStyle = new Style(typeof(TextBox));
            editingElementStyle.Setters.Add(textWrappingSetter);

            var dataGridTextColumn = (DataGridTextColumn)e.Column;
            dataGridTextColumn.ElementStyle = elementStyle;
            dataGridTextColumn.EditingElementStyle = editingElementStyle;

            e.Column.Width = 300;
         }
      }
      else
      {
         e.Cancel = true;
      }
   }
}
公共类AutoHeaderBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.AutoGeneratingColumn+=OnGeneratingColumn;
}
附加时受保护的覆盖无效()
{
AssociatedObject.AutoGeneratingColumn-=OnGeneratingColumn;
base.OnDetaching();
}
生成列上的私有void(对象发送方,DataGridAutoGeneratingColumnEventArgs e)
{
if(例如,PropertyDescriptor是PropertyDescriptor描述符)
{
e、 Column.Header=descriptor.DisplayName??descriptor.Name;
if(descriptor.DisplayName==“Description”)
{
var textWrappingSetter=新设置器
{
Property=TextBox.TextWrappingProperty,
Value=TextWrapping.Wrap
};
//非编辑模式(文本块)的样式
var elementStyle=新样式(typeof(TextBlock));
elementStyle.Setters.Add(textWrappingSetter);
//编辑模式的样式(文本框)
var editingElementStyle=新样式(typeof(TextBox));
editingElementStyle.Setters.Add(textWrappingSetter);
var dataGridTextColumn=(dataGridTextColumn)e.Column;
dataGridTextColumn.ElementStyle=ElementStyle;
dataGridTextColumn.EditingElementStyle=EditingElementStyle;
e、 列宽=300;
}
}
其他的
{
e、 取消=真;
}
}
}

好吧,在处理这个问题几个小时后,我决定完全替换该列来解决这个问题

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;
}

我按照指示修改了代码;不幸的是,文本框仍然没有包装。但是,感谢您提供关于两种编辑/非编辑样式的信息;好消息。我确实提出了一个完全不同的解决方案(添加答案)。@Los2000我测试了它,它运行正常,可能有不同的问题。我建议您在空白解决方案或项目中进行测试。这有助于找出问题所在。很好,您找到了一个适合您的解决方案,但是它似乎增加了复杂性,包括创建带有绑定的新模板列,因此可能值得研究这个问题,但如果它符合您的要求,也可以。我同意它确实增加了复杂性,在XAML之外摆弄框架对象的绑定和模板对我来说有点代码味道;这就是为什么我问了最初的问题。无论如何,任何有相同问题的人都能找到有效的解决方案。如果我弄明白为什么你的解决方案对我不起作用,我会留下评论。