简体   繁体   中英

WPF - How to apply converter to all DataGridTextColumn?

I would like using WPF Apply Converter to Binding Value to all DataGridTextColumn in application.

For single DataGridTextColumn converter working fine:

<DataGridTextColumn 
    Header ="Value" 
    Binding="{Binding Value, Converter={StaticResource decimalConverter}}" 
    />

But in application I got many (over 100) DataGridTextColumn in different DataGrid's and I would know best solution for that instead of applying for each columns converter separately.

I know using Style there is possibility to modify some property for all Type of controls (eg foreground) but not sure how use these for the Binding Value and Converter?

You can do it with the help of global style and attached property. You cannot create global style (or any style) for DataGridTextColumn because it does not inherit from FrameworkElement . But you can create style for DataGrid itself, set attached property for grid in that style, and in property changed handler of that attached property set converter for all column bindings when they are added. Sample code:

public class DataGridHelper : DependencyObject {
    public static IValueConverter GetConverter(DependencyObject obj) {
        return (IValueConverter) obj.GetValue(ConverterProperty);
    }

    public static void SetConverter(DependencyObject obj, IValueConverter value) {
        obj.SetValue(ConverterProperty, value);
    }

    public static readonly DependencyProperty ConverterProperty =
        DependencyProperty.RegisterAttached("Converter", typeof(IValueConverter), typeof(DataGridHelper), new PropertyMetadata(null, OnConverterChanged));

    private static void OnConverterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        // here we have our converter
        var converter = (IValueConverter) e.NewValue;
        // first modify binding of all existing columns if any
        foreach (var column in ((DataGrid) d).Columns.OfType<DataGridTextColumn>()) {
            if (column.Binding != null && column.Binding is Binding)
            {
                ((Binding)column.Binding).Converter = converter;
            }
        }
        // then subscribe to columns changed event and modify binding of all added columns
        ((DataGrid) d).Columns.CollectionChanged += (sender, args) => {
            if (args.NewItems != null) {
                foreach (var column in args.NewItems.OfType<DataGridTextColumn>()) {
                    if (column.Binding != null && column.Binding is Binding) {
                        ((Binding) column.Binding).Converter = converter;
                    }
                }
            }
        };
    }
}

Then create global style somewhere (like App.xaml):

<Application.Resources>
    <local:TestConverter x:Key="decimalConverter" />
    <Style TargetType="DataGrid">
        <Setter Property="local:DataGridHelper.Converter"
                Value="{StaticResource decimalConverter}" />
    </Style>
</Application.Resources>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM