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

要求很简单,根据传入的数据,通过 IValueConverter 返回不同的样式,绑定至 DataGrid 的列(单元格)中,如图:

效果

 

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 " ];


不知各位有没有更方便的方法?或者网络上早已有正解~~~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值