Принудительно регенерировать WPF DataGrid - PullRequest
6 голосов
/ 29 сентября 2011

У меня есть пользовательский элемент управления, который наследуется от DataGrid и в основном является 2D DataGrid (принимает ItemsSource с двумя измерениями, такими как double[,]).

Я добавил конкретные DependencyProperty, которые ColumnHeaders и RowHeaders, чтобы я мог их определить.

Вот как это работает прямо сейчас:

  • Я связываю 2D ItemsSource с DataGrid
  • Метод-обертка использует этот источник для преобразования его в классический IEnumerable, привязываемый к фактической сетке данных ItemsSource
  • Каждая автоматически генерируемая строка / столбец выполняется с использованием событий AutoGeneratingColumn & AutoGeneratingRow для определения их заголовка

Проблема здесь:

Когда я инициализирую DataGrid, все работает нормально.

После этого один из вариантов использования моего приложения определяет, что могут изменяться только заголовки столбцов (путем изменения DependencyProperty ColumnHeaders

И, что бы я здесь ни делал, 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
    }

Ответы [ 2 ]

7 голосов
/ 29 сентября 2011

Сбросьте ваш ItemsSource, и он должен перерисовать вашу DataGrid

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

Возможно, вы также сможете обновить привязку, но я не проверял ее, чтобы увидеть, действительно ли это восстановит DataGrid:

void ResetDataGrid()
{
    myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget();
}
3 голосов
/ 10 апреля 2012

Отключение и последующее включение AutogeneratedColumns приведет к автоматической генерации столбцов.

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