要求很简单,根据传入的数据,通过 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
"
];
不知各位有没有更方便的方法?或者网络上早已有正解~~~~