如何通过IValueConverter为DataGrid的列绑定样式?

效果:

如何通过IValueConverter为DataGrid的列绑定样式?_第1张图片

App.xaml

 
   
   
< Application xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" x:Class ="SilverlightApplication15.App" xmlns:app ="clr-namespace:SilverlightApplication15" > < Application.Resources > < app:DemoComparableConverter x:Key ="ComparableConverter" /> </ Application.Resources > </ Application >

Page1.xaml

   
   
< UserControl x:Class ="SilverlightApplication15.Page1" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d ="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable ="d" d:DesignHeight ="300" d:DesignWidth ="400" xmlns:sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" > < Grid x:Name ="LayoutRoot" Background ="White" > < sdk:DataGrid AutoGenerateColumns ="False" Name ="dataGrid1" > < sdk:DataGrid.Columns > < sdk:DataGridTextColumn Binding ="{Binding Caption}" Header ="Caption" /> < sdk:DataGridTextColumn Binding ="{Binding Value}" Header ="Value" /> < sdk:DataGridTemplateColumn Header ="Value" > < sdk:DataGridTemplateColumn.CellTemplate > < DataTemplate > < TextBlock Text ="{Binding Value}" VerticalAlignment ="Center" Style ="{Binding Converter={StaticResource ComparableConverter}}" /> </ DataTemplate > </ sdk:DataGridTemplateColumn.CellTemplate > </ sdk:DataGridTemplateColumn > </ sdk:DataGrid.Columns > </ sdk:DataGrid > </ Grid > </ UserControl >


PS:这是在2010 RC中生成的代码,发现 DataGrid 的引用不是来自程序集了,而是来自 xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

Page1.xaml.cs

   
   
namespace SilverlightApplication15 { public partial class Page1 : UserControl { public Page1() { InitializeComponent(); this .Loaded += (sender ,e) => { this .BindControls(); }; } void BindControls() { ObservableCollection < DemoComparableClass > demos = new ObservableCollection < DemoComparableClass > (); demos.Add( new DemoComparableClass( " 名称A " , 101 ) ); demos.Add( new DemoComparableClass( " 名称B " , 51 )); demos.Add( new DemoComparableClass( " 名称C " , 201 )); this .dataGrid1.ItemsSource = demos; } } }


其他 class
   
   using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace SilverlightApplication15
{
    public enum Results
    {
        Normal , Above , Below
    }
    public class DemoComparableClass
    {
        public string Caption { get; set; }

        public int Value { get; set; }

        public DemoComparableClass(string c , int v)
        {
            this.Caption = c;
            this.Value = v;
        }

        public Results Result
        {
            get
            {
                if (this.Value > 100 && this.Value < 200)
                {
                    return Results.Normal;
                }
                else if (this.Value >= 200)
                {
                    return Results.Above;
                }
                else 
                {
                    return Results.Below;
                }
            }
        }
    }

    public class DemoComparableConverter : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is DemoComparableClass)
            {
                DemoComparableClass v = (DemoComparableClass)value;
                if (targetType.Equals(typeof(Style)))
                {
                    Style s = new Style(typeof(TextBlock));
                    switch (v.Result)
                    {
                        case Results.Normal:
                            s.Setters.Add(new Setter(TextBlock.ForegroundProperty , new SolidColorBrush(Colors.Brown)));
                            break;
                        case Results.Above:
                            s.Setters.Add(new Setter(TextBlock.ForegroundProperty , new SolidColorBrush(Colors.Red)));
                            s.Setters.Add(new Setter(TextBlock.FontWeightProperty, FontWeights.Bold ));
                            break;
                        case Results.Below:
                            s.Setters.Add(new Setter(TextBlock.ForegroundProperty , new SolidColorBrush(Colors.Green)));
                            break;
                    }
                    return s;
                }
                else if (targetType.Equals(typeof(Brush)))
                {
                    switch (v.Result)
                    {
                        case Results.Normal:
                            return new SolidColorBrush(Colors.Brown);
                        case Results.Above:
                            return new SolidColorBrush(Colors.Red);
                        case Results.Below:
                            return new SolidColorBrush(Colors.Green);
                    }
                }
            }
            return null;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

要实现的功能很简单,就是通过 DemoComparableConverter 让 DataGrid 中的单元格显示出不同的样式,我试了半天,得出几点:
1. DataGridTextColumn 只有一个依赖项属性 FontFamilyProperty ,无法以

  < sdk:DataGridTextColumn Binding ="{Binding Value}"   Header ="Value"
                   Foreground
="{Binding Converter={StaticResource ComparableConverter}}" />
方式进行绑定;

2. 似乎只能使用 DataGridTemplateColumn ,并对 DataTemplate 中的控件进行 Style、Foreground、Background 等依赖项属性的绑定了;

3. 如果碰上要动态的为DataGrid添加列的情况(如上面的效果图所示,“单价、价格、交货日期”等列是根据用户的选择而决定要不要显示的,可能还会有诸如“运费、管理费、折扣率、税收”等等可供选择的列,又或者是要显示各个代理商在1-12月的销售情况的数据透视表,这些都是动态显示列的例子),则只能通过后台代码为 DataGrid 增加DataGridTemplateColumn ,那么如何在代码中为 DataTemplate 中的控件进行 Style、Foreground、Background 等依赖项属性的绑定? 目前我是通过加载动态 DataTemplate 来实现,感觉比较麻烦:
   
   DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = header; // header 为表头标题
col.CellTemplate = (DataTemplate)System.Windows.Markup.XamlReader.Load(
                        GetNumericTemplate(propertyName)); // propertyName 为要被绑定的属性名

public string GetDateTemplate(string propertyName)
{
        string template = @"
<DataTemplate
    xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
            <TextBlock Text='{Binding @PropertyName}' 
                       Style='{Binding Converter={StaticResource ComparableConverter}}'
                        VerticalAlignment='Center' />
</DataTemplate>";
       return template.Replace("@PropertyName", propertyName);
}


加载动态 DataTemplate 还可以直接使用 Resources ,但是我不知道该如何动态的指定 propertyName

    col.CellTemplate = (DataTemplate) this .Resources[ " ADataTemplate " ];


不知各位有没有更方便的方法?或者网络上早已有正解~~~~

你可能感兴趣的:(Converter)