通过AttachedProperty设置所有DataGridTextColumns的样式 [英] Style all DataGridTextColumns via AttachedProperty

查看:142
本文介绍了通过AttachedProperty设置所有DataGridTextColumns的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的是创建一个 Style 以便在<$ c中的所有 DataGridTextColumns 上应用一个自动换行$ c> Datagrid ,而无需像这样显式设置。

What I tried to do is create a Style to apply a WordWrap on all DataGridTextColumns in a Datagrid without explicitly setting it like this.

<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

Unfortunately it is not possible to use some Style as below directly, because DataGridTextColumn isn't a FrameworkElement.

<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
    <Setter Property="TextWrapping" Value="Wrap"/>
</Style>

我发现此解决方法 https://stackoverflow.com/a/2640862/5381620 ,并试图弄清楚它是如何工作的。但是,我不熟悉附加属性,因此不明白为什么它不起作用。

I found this workaround https://stackoverflow.com/a/2640862/5381620 by RayBurns and was trying to figure out how it's working. However, I'm new to attached properties and therefore don't understand why it is not working.

c#代码似乎还可以。

The c# code seems to be ok.

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);
    }
}

我完全感到困惑的是,当我们开始弄清楚样式设置器。
目前,我正在尝试这种方式,这显然行不通,但实际上我不知道此目标类型应该是什么样子。

I got totally confused is when we get towards figuring out the style setter. Currently I'm trying it this way, which is obviously not working, but actually I don't have a clue what this targettype should really look like.

<local:MyDataGridHelper.TextColumnStyle>
    <Style TargetType="FrameworkElement">
        <Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
    </Style>
</local:MyDataGridHelper.TextColumnStyle>


推荐答案

您应设置 ElementStyle列的附加属性的值:

You should set the ElementStyle of the columns to the value of the attached property:

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>

这篇关于通过AttachedProperty设置所有DataGridTextColumns的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆