强制 WPF DataGrid 自行重新生成

发布于 2024-12-07 07:45:22 字数 2758 浏览 0 评论 0原文

我有一个继承自 DataGrid 的自定义控件,基本上是一个 2D DataGrid (接受具有二维的 ItemsSource ,例如 double [,] )。

我添加了一个特定的DependencyProperty,即ColumnHeadersRowHeaders,以便我可以定义它们。

它现在的工作原理如下:

  • 我将 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 the DataGrid
  • A wrapper method will take this source to transform it to a classic IEnumerable bindable to the actual datagrid's ItemsSource
  • 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉生梦死 2024-12-14 07:45:22

重置您的 ItemsSource,它应该重新绘制您的 DataGrid

void ResetDataGrid()
{
    var temp = myDataGrid.ItemsSource;
    myDataGrid.ItemsSource = null;
    myDataGrid.ItemsSource = temp;
}

您也可以刷新绑定,但我还没有测试它以查看这是否会真正重新生成 DataGrid:

void ResetDataGrid()
{
    myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget();
}

Reset your ItemsSource and it should redraw your DataGrid

void ResetDataGrid()
{
    var temp = myDataGrid.ItemsSource;
    myDataGrid.ItemsSource = null;
    myDataGrid.ItemsSource = temp;
}

You might also be able to refresh the binding, but I haven't tested it to see if this will actually regenerate the DataGrid:

void ResetDataGrid()
{
    myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget();
}
淡写薰衣草的香 2024-12-14 07:45:22

关闭然后打开 Auto generatedColumns 将导致再次自动生成列。

dataGrid.AutoGenerateColumns = false;
dataGrid.AutoGenerateColumns = true;

Toggling AutogeneratedColumns off and then on will cause the columns to be automatically generated again.

dataGrid.AutoGenerateColumns = false;
dataGrid.AutoGenerateColumns = true;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文