通过附加属性设置所有 DataGridTextColumn 的样式
Style all DataGridTextColumns via AttachedProperty
我尝试做的是创建一个 Style
以在 Datagrid
中的所有 DataGridTextColumns
上应用 WordWrap,而不是像这样明确设置它。
<DataGrid ItemsSource="{Binding Lines}">
<DataGrid.Columns>
<DataGridTextColumn Header="Column1" Binding="{Binding Path=Result1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
不幸的是,无法直接使用下面的一些 Style
,因为 DataGridTextColumn
不是 FrameworkElement
。
<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
我发现了 RayBurns 的解决方法,并试图弄清楚它是如何工作的。但是,我是附加属性的新手,因此不明白为什么它不起作用。
c#代码好像没问题。
public class MyDataGridHelper : DependencyObject
{
private static readonly DependencyProperty TextColumnStyleProperty = DependencyProperty.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);
};
}
});
public static void SetTextColumnStyle(DependencyObject element, Style value)
{
element.SetValue(TextColumnStyleProperty, value);
}
public static Style GetTextColumnStyle(DependencyObject element)
{
return (Style)element.GetValue(TextColumnStyleProperty);
}
private static void UpdateColumnStyles(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, (BindingBase)setter.Value);
else
column.SetValue(setter.Property, setter.Value);
}
}
当我们着手确定样式时,我完全感到困惑 setter。
目前我正在尝试这种方式,这显然不起作用,但实际上我不知道这个目标类型应该是什么样子。
<local:MyDataGridHelper.TextColumnStyle>
<Style TargetType="FrameworkElement">
<Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
</Style>
</local:MyDataGridHelper.TextColumnStyle>
您应该将列的 ElementStyle
设置为附加的值 属性:
public class MyDataGridHelper : DependencyObject
{
private static readonly DependencyProperty TextColumnStyleProperty =
DependencyProperty.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);
};
}
});
public static void SetTextColumnStyle(DependencyObject element, Style value)
{
element.SetValue(TextColumnStyleProperty, value);
}
public static Style GetTextColumnStyle(DependencyObject element)
{
return (Style)element.GetValue(TextColumnStyleProperty);
}
private static void UpdateColumnStyles(DataGrid grid)
{
var style = GetTextColumnStyle(grid);
foreach (var column in grid.Columns.OfType<DataGridTextColumn>())
column.ElementStyle = style;
}
}
用法:
<DataGrid>
<local:MyDataGridHelper.TextColumnStyle>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</local:MyDataGridHelper.TextColumnStyle>
...
</DataGrid>
我尝试做的是创建一个 Style
以在 Datagrid
中的所有 DataGridTextColumns
上应用 WordWrap,而不是像这样明确设置它。
<DataGrid ItemsSource="{Binding Lines}">
<DataGrid.Columns>
<DataGridTextColumn Header="Column1" Binding="{Binding Path=Result1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
不幸的是,无法直接使用下面的一些 Style
,因为 DataGridTextColumn
不是 FrameworkElement
。
<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
我发现了 RayBurns 的解决方法,并试图弄清楚它是如何工作的。但是,我是附加属性的新手,因此不明白为什么它不起作用。
c#代码好像没问题。
public class MyDataGridHelper : DependencyObject
{
private static readonly DependencyProperty TextColumnStyleProperty = DependencyProperty.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);
};
}
});
public static void SetTextColumnStyle(DependencyObject element, Style value)
{
element.SetValue(TextColumnStyleProperty, value);
}
public static Style GetTextColumnStyle(DependencyObject element)
{
return (Style)element.GetValue(TextColumnStyleProperty);
}
private static void UpdateColumnStyles(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, (BindingBase)setter.Value);
else
column.SetValue(setter.Property, setter.Value);
}
}
当我们着手确定样式时,我完全感到困惑 setter。 目前我正在尝试这种方式,这显然不起作用,但实际上我不知道这个目标类型应该是什么样子。
<local:MyDataGridHelper.TextColumnStyle>
<Style TargetType="FrameworkElement">
<Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
</Style>
</local:MyDataGridHelper.TextColumnStyle>
您应该将列的 ElementStyle
设置为附加的值 属性:
public class MyDataGridHelper : DependencyObject
{
private static readonly DependencyProperty TextColumnStyleProperty =
DependencyProperty.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);
};
}
});
public static void SetTextColumnStyle(DependencyObject element, Style value)
{
element.SetValue(TextColumnStyleProperty, value);
}
public static Style GetTextColumnStyle(DependencyObject element)
{
return (Style)element.GetValue(TextColumnStyleProperty);
}
private static void UpdateColumnStyles(DataGrid grid)
{
var style = GetTextColumnStyle(grid);
foreach (var column in grid.Columns.OfType<DataGridTextColumn>())
column.ElementStyle = style;
}
}
用法:
<DataGrid>
<local:MyDataGridHelper.TextColumnStyle>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</local:MyDataGridHelper.TextColumnStyle>
...
</DataGrid>