gpt4 book ai didi

c# - 在动态 DataGrid 中启用 TextWrap

转载 作者:行者123 更新时间:2023-11-30 21:09:06 26 4
gpt4 key购买 nike

我正在动态生成一个 DataGrid 并将其添加到我的 WPF 应用程序的 StackPanel 中。

由于是动态生成的,因此在 XAML 端没有相同的标记,我需要以编程方式管理绑定(bind)和所有属性。

如果文本很长,我希望我的 DataGrid 将单元格中的值换行到下一行。我知道我需要用 TextBlock 替换 DataGridCell 并在其上设置 TextWrap 属性。我发现的所有例子本身都暗示了这些方面的一些东西。但是,在没有 XAML 的情况下,我无法找到完全从代码隐藏完成此操作的方法。

到目前为止,我已经尝试了以下代码,但它不起作用。

DataGrid dg = new DataGrid();   

dg.ItemsSource = ((DataSet)data).Tables[0].DefaultView;
dg.DataContext = ((DataSet)data).Tables[0].DefaultView;

DataTemplate ct = new DataTemplate(typeof(DataGridCell));
FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
tb.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
ct.VisualTree = tb;

dg.ItemTemplate = ct;
dg.ColumnWidth = 300;

你能给我指出正确的方向吗?

[更新]:解决方案

经过进一步研究,我找到了解决问题的办法。对于自动生成的列,我们需要捕获 AutoGeneratingColumn 事件并将默认的 DataGridTextColumn 替换为具有 TextBlock< 的 DataGridTemplateColumn/ 在里面。然后我们可以设置“TextWrappingProperty”来让文本换行。

更新后的代码如下:

DataGrid dg = new DataGrid();   

dg.ItemsSource = ((DataSet)data).Tables[0].DefaultView;
dg.DataContext = ((DataSet)data).Tables[0].DefaultView;

DataTemplate ct = new DataTemplate(typeof(DataGridCell));
FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
tb.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
ct.VisualTree = tb;

dg.AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(dg_AutoGeneratingColumn);

dg.MaxColumnWidth = 300;

然后是事件处理器下的代码:

 private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
//cancel the auto generated column
e.Cancel = true;

//Get the existing column
DataGridTextColumn dgTextC = (DataGridTextColumn)e.Column;

//Create a new template column
DataGridTemplateColumn dgtc = new DataGridTemplateColumn();

DataTemplate dataTemplate = new DataTemplate(typeof(DataGridCell));

FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
tb.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
dataTemplate.VisualTree = tb;

dgtc.Header = dgTextC.Header;
dgtc.CellTemplate = dataTemplate;

tb.SetBinding(TextBlock.TextProperty, dgTextC.Binding);

//add column back to data grid
DataGrid dg = sender as DataGrid;
dg.Columns.Add(dgtc);
}

最佳答案

另一种方法是使用这样的行为。

  public class DataGridWrapTextBehaviour : Behavior<DataGrid>
{
private DataGrid DataGrid
{
get { return AssociatedObject as DataGrid; }
}

private Style ElementStyle { get; set; }
private Style EditingElementStyle { get; set; }

protected override void OnAttached()
{
base.OnAttached();

this.ElementStyle = new Style( typeof( TextBlock ) );
this.ElementStyle.Setters.Add( new Setter( TextBlock.TextWrappingProperty, TextWrapping.Wrap ) );

this.EditingElementStyle = new Style( typeof( TextBox ) );
this.EditingElementStyle.Setters.Add( new Setter( TextBox.TextWrappingProperty, TextWrapping.Wrap ) );

this.DataGrid.Columns.CollectionChanged += Columns_CollectionChanged;
}

protected override void OnDetaching()
{
this.DataGrid.Columns.CollectionChanged -= Columns_CollectionChanged;
base.OnDetaching();
}

private void Columns_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
{
foreach ( var column in this.DataGrid.Columns.OfType<DataGridTextColumn>() )
{
column.ElementStyle = this.ElementStyle;
column.EditingElementStyle = this.EditingElementStyle;
}
}
}

然后您可以将行为拖放到 Expression Blend 中的 DataGrid 上。

关于c# - 在动态 DataGrid 中启用 TextWrap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9223867/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com