Почему я не могу разработать DataGridTextColumn?

Я пытался создать Стиль для DataGridTextColumn со следующим кодом

<Style TargetType="{x:Type DataGridTextColumn}">
           ...
</Style>

Однако выделения Visual Studio 2010 {x:Type DataGridTextColumn} с синей строкой и уточняет: Exception has been thrown by the target of an invocation.

Почему это происходит и как я фиксирую его?

34
задан M.Stramm 18 December 2015 в 13:44
поделиться

1 ответ

Нельзя стилизовать DataGridTextColumn , потому что DataGridTextColumn не является производным от FrameworkElement (или FrameworkContentElement ). Только FrameworkElement и т. Д. Поддерживает стили.

Когда вы пытаетесь создать стиль в XAML для любого типа, кроме FrameworkElement или FrameworkContentElement , вы получаете это сообщение об ошибке.

Как вы это решите? Как и в случае с любой проблемой, там, где есть желание, есть выход. В этом случае я думаю, что самое простое решение - создать присоединенное свойство для DataGrid, чтобы назначить стиль DataGridColumn:

<DataGrid ...>
  <local:MyDataGridHelper.TextColumnStyle>
    <Style TargetType="FrameworkElement">
      ... setters here ...
    </Style>
  </local:MyDataGridHelper.TextColumnStyle>
  ...

Реализация будет примерно такой:

public class MyDataGridHelper : DependencyObject
{
  // Use propa snipped to create attached TextColumnStyle with metadata:
  ... RegisterAttached("TextColumnStyle", typeof(Style), typeof(MyDataGridHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
    {
      var grid = (DataGrid)obj;
      if(e.OldValue==null && e.NewValue!=null)
        grid.Columns.CollectionChanged += (obj2, e2) =>
        {
          UpdateColumnStyles(grid);
        }
    }
  }
  private void UpdateStyles(DataGrid grid)
  {
    var style = GetTextColumnStyle(grid);
    foreach(var column in grid.Columns.OfType<DataGridTextColumn>())
      foreach(var setter in style.Setters.OfType<Setter>())
        if(setter.Value is BindingBase)
          BindingOperations.SetBinding(column, setter.Property, setter.Value);
        else
          column.SetValue(setter.Property, setter.Value);
  }
}

Как это работает, каждый раз, когда присоединенное свойство изменяется , для события Columns.CollectionChanged в сетке добавляется обработчик. Когда запускается событие CollectionChanged, все столбцы обновляются в соответствии с заданным стилем.

Обратите внимание, что приведенный выше код не обрабатывает ситуацию, когда стиль удаляется и снова добавляется аккуратно: регистрируются два обработчика событий. Для действительно надежного решения вы хотели бы исправить это, добавив еще одно присоединенное свойство, содержащее обработчик событий, чтобы обработчик событий мог быть отменен, но для ваших целей я думаю, что это неважно.

Еще одно предостережение заключается в том, что прямое использование SetBinding и SetValue приведет к тому, что DependencyProperty будет иметь BaseValueSource Local вместо DefaultStyle . В вашем случае это, вероятно, не будет иметь никакого значения, но я подумал, что должен упомянуть об этом.

25
ответ дан 27 November 2019 в 17:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: