Вы не можете стилизовать 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
. Это, вероятно, не будет иметь никакого значения в вашем случае, но я подумал, что должен упомянуть об этом.