【问题标题】:Set Text Wrapping for an AutoGenerated DataGrid TextBox using a behavior使用行为为自动生成的 DataGrid 文本框设置文本换行
【发布时间】:2020-11-05 21:29:09
【问题描述】:

我正在尝试设置自动生成的DataGrid 列的TextBox 以使用行为来换行文本。但是,在AutoGeneratingColumn 事件期间设置属性不起作用。我设置了正确的属性还是有什么问题?

这是DataGrid 的 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;
   }
}

【问题讨论】:

    标签: c# wpf mvvm datagrid


    【解决方案1】:

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

    • 在非编辑模式下,它使用ElementStyle 属性中的样式显示TextBlock。
    • 在编辑模式下,它使用EditingElementStyle 属性中的样式显示TextBox。

    您的代码中的问题是您将编辑样式应用于非编辑样式属性。我已经调整了您的行为代码,以在编辑和非编辑模式下包装文本。如果您只想在编辑模式下换行,只需删除 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;
          }
       }
    }
    

    【讨论】:

    • 我按照说明修改了代码;不幸的是,TextBox 仍然没有换行。但是,感谢您提供有关两种编辑/非编辑样式的信息;要知道的好信息。我确实想出了一个完全不同的解决方案(添加答案)。
    • @Los2000 我测试了它并且它有效,也许有一个不同的问题。我建议您在空白解决方案或项目中对此进行测试。它可以帮助找出问题所在。很高兴您找到了一个适合您的解决方案,但它似乎增加了复杂性,包括创建一个带有绑定的新模板列,因此可能值得调查这个问题,但如果它符合您的要求,也可以.
    • 我同意它确实增加了复杂性,并且在 XAML 之外摆弄框架对象的绑定和模板对我来说有点代码味道;这就是为什么我问我原来的问题。无论如何,任何有相同问题的人都可以找到有效的解决方案。如果我弄清楚为什么您的解决方案对我不起作用,我会发表评论。
    【解决方案2】:

    好吧,在解决这个问题几个小时后,我决定通过完全更换色谱柱来解决这个问题。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      相关资源
      最近更新 更多