【问题标题】:Force WPF DataGrid to regenerate itself强制 WPF DataGrid 重新生成自身
【发布时间】:2011-11-27 13:51:21
【问题描述】:

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

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

这是它现在的工作方式:

  • 我将 2D ItemsSource 绑定到 DataGrid
  • 包装器方法将使用此源将其转换为经典的IEnumerable,可绑定到实际数据网格的ItemsSource
  • 自动生成的每一行/每一列都是使用事件 AutoGeneratingColumnAutoGeneratingRow 完成的,以便定义它们的标题

这里的问题:

当我初始化 DataGrid 时,一切正常。

之后,我的应用程序的一个用例定义只有列标题可以更改(通过修改DependencyPropertyColumnHeaders

而且,无论我在这里做什么,DataGrid 都不会重新自动生成其列(因此,标题不会以任何方式更改)。

那么,有没有办法向DataGrid 询问类似“嘿,我希望你从头开始并重新生成你的列”之类的问题?因为目前我无法到达AutoGeneratingColumn 事件,调用诸如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
    }

【问题讨论】:

  • 为什么不尝试重置 ItemsSource 属性
  • 它确实有效(我不敢相信我之前没有考虑过 -__- ),但是有什么“更聪明”的方法可以做到这一点吗?
  • @Damascus 你有没有找到比取消设置和设置 itemssource 更聪明的方法?我也在找那个。

标签: wpf data-binding datagrid auto-generate


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗨,刷新不起作用,因为 WPF 将首先自动检查绑定属性是否实际更改(不是这种情况)重置 itemssource 工作正常,但我想知道是否没有“更优雅”的解决方案?
【解决方案2】:

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

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

【讨论】:

  • 我有一个与 OP 类似的场景,这个解决方案比其他解决方案效果更好。出于某种原因,直接弄乱 ItemsSource 会导致自动生成不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 2011-05-05
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
相关资源
最近更新 更多