强制 WPF DataGrid 自行重新生成
我有一个继承自 DataGrid
的自定义控件,基本上是一个 2D DataGrid
(接受具有二维的 ItemsSource
,例如 double [,]
)。
我添加了一个特定的DependencyProperty
,即ColumnHeaders
和RowHeaders
,以便我可以定义它们。
它现在的工作原理如下:
- 我将 2D
ItemsSource
绑定到DataGrid
- 包装器方法将采用此源将其转换为经典的
IEnumerable
> 可绑定到实际数据网格的ItemsSource
- 自动生成的每一行/列都是使用事件
AutoGenerateColumn
& 完成的AutoGenerateRow
以便定义其标头
这里的问题:
当我初始化 DataGrid
时,一切正常。
之后,我的应用程序的用例之一定义只有列标题可以更改(通过修改 DependencyProperty
ColumnHeaders
而且,无论我在这里做什么,>DataGrid
不会重新自动生成其列(因此,标题不会以任何方式更改)
因此,有没有办法向 DataGrid
询问类似“嘿”的内容 。 ,我要你重新开始从头开始并重新生成您的列”?因为目前,我无法访问 AutoGenerateColumn
事件,并且调用诸如 InvalidateVisual
之类的方法只会重绘网格(而不是 )。
重新生成列
我不确定我们是否需要一些代码,但是......我会放一些代码,这样就没有人需要它了:D
/// <summary>
/// IList of String containing column headers
/// </summary>
public static readonly DependencyProperty ColumnHeadersProperty =
DependencyProperty.Register("ColumnHeaders",
typeof(IEnumerable),
typeof(FormattedDataGrid2D),
new PropertyMetadata(HeadersChanged));
/// <summary>
/// Handler called when the binding on ItemsSource2D changed
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private static void ItemsSource2DPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
FormattedDataGrid2D @this = source as FormattedDataGrid2D;
@this.OnItemsSource2DChanged(e.OldValue as IEnumerable, e.NewValue as IEnumerable);
}
// (in the constructor)
AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGrid2D_AutoGeneratingColumn);
void DataGrid2D_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridTextColumn column = e.Column as DataGridTextColumn;
column.Header = (ColumnHeaders == null) ? columnIndex++ : (ColumnHeaders as IList)[columnIndex++]; //Header will be the defined header OR the column number
column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto);
Binding binding = column.Binding as Binding;
binding.Path = new PropertyPath(binding.Path.Path + ".Value"); // Workaround to get a good value to display, do not take care of that
}
I have a custom control which inherits from DataGrid
and is basically a 2D DataGrid
(accepts an ItemsSource
with two dimensions, such as double[,]
).
I added a specific DependencyProperty
which is ColumnHeaders
and RowHeaders
so I can define them.
Here is how it works right now:
- I bind a 2D
ItemsSource
to theDataGrid
- A wrapper method will take this source to transform it to a classic
IEnumerable
bindable to the actual datagrid'sItemsSource
- Each row / column auto-generated is done using the events
AutoGeneratingColumn
&AutoGeneratingRow
in order to define their header
The problem here:
When I initialize the DataGrid
, everything works fine.
After that, one of the use-cases of my application defines that only the column headers can change (by modifying the DependencyProperty
ColumnHeaders
And, whatever I do here, the DataGrid
won't re-autogenerate its columns (and therefore, headers won't be changed in any way).
So, is there a way to ask the DataGrid
something like "Hey, I want you to restart from scratch and regenerate your columns" ? Because for now, I can't reach the AutoGeneratingColumn
event, and calling a method such as InvalidateVisual
will just redraw the grid (and not regenerate columns).
Any ideas here?
I'm not sure that we need some code but... I'll put some so nobody asks for it :D
/// <summary>
/// IList of String containing column headers
/// </summary>
public static readonly DependencyProperty ColumnHeadersProperty =
DependencyProperty.Register("ColumnHeaders",
typeof(IEnumerable),
typeof(FormattedDataGrid2D),
new PropertyMetadata(HeadersChanged));
/// <summary>
/// Handler called when the binding on ItemsSource2D changed
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private static void ItemsSource2DPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
FormattedDataGrid2D @this = source as FormattedDataGrid2D;
@this.OnItemsSource2DChanged(e.OldValue as IEnumerable, e.NewValue as IEnumerable);
}
// (in the constructor)
AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGrid2D_AutoGeneratingColumn);
void DataGrid2D_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridTextColumn column = e.Column as DataGridTextColumn;
column.Header = (ColumnHeaders == null) ? columnIndex++ : (ColumnHeaders as IList)[columnIndex++]; //Header will be the defined header OR the column number
column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto);
Binding binding = column.Binding as Binding;
binding.Path = new PropertyPath(binding.Path.Path + ".Value"); // Workaround to get a good value to display, do not take care of that
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
重置您的 ItemsSource,它应该重新绘制您的 DataGrid
您也可以刷新绑定,但我还没有测试它以查看这是否会真正重新生成 DataGrid:
Reset your ItemsSource and it should redraw your DataGrid
You might also be able to refresh the binding, but I haven't tested it to see if this will actually regenerate the DataGrid:
关闭然后打开 Auto generatedColumns 将导致再次自动生成列。
Toggling AutogeneratedColumns off and then on will cause the columns to be automatically generated again.