Я создал матричный элемент управления, производный от DataGrid
, который должен отображать сложные типы в ячейках. Эти сложные типы должны затем быть стилизованы шаблоном.
При использовании AutoGenerateColumns
DataGrid
автоматически создает столбцы и типы ячеек на основе типа списка, назначенного для ItemsSource
.
Я хочу заменить строку, столбец и тип ячейки сетки для выполнения пользовательских операций и привязок с привязкой к ней модели представления. Я уже смог создать пользовательские строку и столбец. Есть ли способ получить из DataGridCell
и заставить сетку данных использовать этот тип вместо типа по умолчанию?
Я посмотрел исходный код .net и увидел, что в строке используется DataGridCellsPresenter
для создания ячеек, но это свойство недоступно.
public class MatrixControl : DataGrid
{
public static readonly DependencyProperty COLUMN_HEADER_TEMPLATE_PROPERTY = DependencyProperty.Register(nameof(ColumnHeaderTemplate), typeof(DataTemplate), typeof(MatrixControl), new PropertyMetadata(default(object)));
public DataTemplate ColumnHeaderTemplate { get { return (DataTemplate)GetValue(COLUMN_HEADER_TEMPLATE_PROPERTY); } set { SetValue(COLUMN_HEADER_TEMPLATE_PROPERTY, value); } }
private MatrixViewModel ViewModel { get { return DataContext as MatrixViewModel; } }
public MatrixControl()
{
DataContextChanged += OnDataContextChanged;
SelectionMode = DataGridSelectionMode.Extended;
SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;
AutoGenerateColumns = true;
}
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ItemsSource = ViewModel.Rows.Select(c => new Row(c, ViewModel));
}
protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
{
e.Cancel = true;
Columns.Clear();
foreach (var column in ViewModel.Columns)
{
Columns.Add(new MatrixColumn(column)
{
HeaderTemplate = ColumnHeaderTemplate
});
}
}
}
class MatrixColumn : DataGridTemplateColumn
{
public object Value { get; }
public MatrixColumn(object value)
{
Value = value;
}
}
class Row
{
public object Value { get; }
public Row(object value)
{
Value = value;
}
}
class MatrixViewModel
{
public IEnumerable<object> Columns { get; set; }
public IEnumerable<object> Rows { get; set; }
}
Обновление: попытка заменить DataGridCellsPresenter
// in data grid class
protected override DependencyObject GetContainerForItemOverride()
{
return new MatrixRow();
}
class MatrixRow : DataGridRow
{
public MatrixRow()
{
var cellPresenterProperty = GetType().GetProperty("CellsPresenter", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty);
cellPresenterProperty.SetValue(this, new MatrixCellPresenter());
}
}
class MatrixCellPresenter : DataGridCellsPresenter
{
protected override DependencyObject GetContainerForItemOverride()
{
// won't get called, the presenter is overriden by the internal one
return new MatrixCell();
}
}