Заставить WPF DataGrid регенерировать себя
У меня есть пользовательский элемент управления, который наследуется от 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 ответа:
Сбросьте свой ItemsSource, и он должен перерисовать вашу DataGrid
void ResetDataGrid() { var temp = myDataGrid.ItemsSource; myDataGrid.ItemsSource = null; myDataGrid.ItemsSource = temp; }
Вы также можете обновить привязку, но я не проверял ее, чтобы увидеть, действительно ли это восстановит DataGrid:
void ResetDataGrid() { myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget(); }