使用行为为 AutoGenerated DataGrid 文本框设置文本换行
Set Text Wrapping for an AutoGenerated DataGrid TextBox using a behavior
我正在尝试将自动生成的 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;
}
}
数据网格列有两种不同的模式,Non-Edit 和 编辑,对于 DataGridTextColumn
:
- 在non-edit模式下,它显示
TextBlock
使用ElementStyle
属性中的样式。
- 在编辑模式下,它使用
EditingElementStyle
属性 中的样式显示 TextBox
。
您的代码中的问题是您将编辑样式应用于 non-edit 样式 属性。我已经调整了您的行为代码以在编辑和 non-edit 模式下包装文本。如果您只想在编辑模式下换行,只需删除 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;
}
}
}
好吧,在摆弄这个问题几个小时后,我决定通过完全更换色谱柱来解决这个问题。
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;
}
我正在尝试将自动生成的 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;
}
}
数据网格列有两种不同的模式,Non-Edit 和 编辑,对于 DataGridTextColumn
:
- 在non-edit模式下,它显示
TextBlock
使用ElementStyle
属性中的样式。 - 在编辑模式下,它使用
EditingElementStyle
属性 中的样式显示TextBox
。
您的代码中的问题是您将编辑样式应用于 non-edit 样式 属性。我已经调整了您的行为代码以在编辑和 non-edit 模式下包装文本。如果您只想在编辑模式下换行,只需删除 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;
}
}
}
好吧,在摆弄这个问题几个小时后,我决定通过完全更换色谱柱来解决这个问题。
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;
}