【WPF】DataGrid的Row样式设置

引言

     在与DataGrid相关的项目中,会有一个比较常见的需求.那就是在根据数据设置行的样式,例如行的背景色或者字体色.我们用到的方法有几个,下面一个个说来.

准备工作

    介绍方法之前,先定义数据类,是一个比较简单的分数表,有姓名,分数等,代码如下:

 

  public class Score
    {
        public string Name { get; set; }
        public int Chinese { get; set; }
        public int Math { get; set; }
    }

 

     再创建个实例给datagrid赋值数据源,如下:

 this.datagrid.ItemsSource = new List<Score> { new Score { Name = "小红", Chinese = 90, Math = 80 }, 
                                                          new Score { Name = "小明", Chinese = 60, Math = 90 },
                                                          new Score { Name = "小李", Chinese = 95, Math = 58 },
                                                          new Score { Name = "小雷", Chinese = 50, Math = 80 }};

1.数据触发器

     最简单最方便的方法就是定义一个DataTrigger,但是缺点也很明显,只能用于单个数据绑定和判断数据是否相等的情况.例如,我们要将语文成绩等于90的数据背景色设置为绿色,代码如下

<Style >       
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Chinese}" Value="90">
                            <Setter Property="DataGridRow.Background" Value="Green"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
</Style>

2.值转换器

   IValueConverter也只能应用于单数据绑定,但是它功能上强大些.例如我们要将语文成绩小于60的数据背景色设置为红色,代码如下:

   定义BlackgroundConverter,如下:

    public class BlackgroundConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (int.Parse(value.ToString(), NumberStyles.Any) < 60)
            {
                
                return new SolidColorBrush(Colors.Red );
            }
            else
            { 
                return DependencyProperty.UnsetValue;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }

定义资源

 <local:BlackgroundConverter x:Key="blackgroudconverter"></local:BlackgroundConverter>

应用转换器

<Style >
   <Setter Property="DataGridRow.Background" Value="{Binding Chinese,Converter={StaticResource blackgroudconverter}}"></Setter>
</Style>

另外,还有一个更强大的值转换器IMultiValueConverter,同时绑定语文和数学成绩,可以将语文成绩大于数学成绩的数据设置为红色,如下:

public class BlackgroudMultiConver : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
            int one = int.Parse(values[0].ToString(), NumberStyles.Any) ;
            int two =  int.Parse(values[1].ToString(), NumberStyles.Any);
           
                if (values[0] != null && values[1] != null && one > two)
                {

                    return new SolidColorBrush(Colors.Red);
                }
                else
                {
                    return DependencyProperty.UnsetValue;

                }
            }
            catch (Exception e)
            {
                return DependencyProperty.UnsetValue;
            }
        
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
        {
            return null;
        }

    }

3.样式选择器

     从功能上看,StyleSelector是上面两个的集大成者.它可以实现多个数据值的判断和应用多个属性的设置.例如,我们可以将语文成绩大于数学成绩的数据设置为红色,字体颜色设置为蓝色,代码如下:

    public class DataGridStyleSelector : StyleSelector
    {

        public override Style SelectStyle(object item, DependencyObject container) 
        {
            if (item is Score)
            {
                Score tmp = (Score)item;
                if (tmp.Chinese > tmp.Math)
                {
                    return style;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;

            } 
        }
        public Style style { get; set; }
    }

 定义资源

<local:DataGridStyleSelector x:Key="dataGridStyleSelector">
                <local:DataGridStyleSelector.style>
                    <Style>
                        <Setter Property="DataGridRow.Background" Value="Red"></Setter>
                        <Setter Property="DataGridRow.Foreground" Value="Blue"></Setter>
                    </Style>
                </local:DataGridStyleSelector.style>
</local:DataGridStyleSelector>

应用样式选择器

 <DataGrid Name="datagrid" AutoGenerateColumns="False"  RowStyleSelector="{StaticResource dataGridStyleSelector}" >

但是,样式选择器也有个不如意的地方,当我们动态编辑数据的时候,不能自动引发样式的改变.这种情况没有优雅的解决方法,只能在数据变化的时候,粗暴地将对应的样式选择器设置null再设置回来.

4.乱入:模板选择器

    DataTemplateSelector同样功能很强大,它可以完全改变数据的显示方式.可惜的是,datagrid没有RowTemplateSelector.只有CellTemplateSelector,我们可以利用CellTemplateSelector对单元格做点有趣的显示,例如添加点额外的文字描述,如下

public class CellDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container) 
        {

            if (item is Score)
            {
                Score tmp = (Score)item;
                if (tmp.Chinese >=60)
                {
                    return template1;
                }
                else
                {
                    return template2;
                }
            }
            else
            {
                return null;

            }
        
        }
        public DataTemplate template1 { get; set; }
        public DataTemplate template2 { get; set; }
    }

定义资源

<local:CellDataTemplateSelector x:Key="celldatatemplateselector">
                <local:CellDataTemplateSelector.template1>
                    <DataTemplate>
                        <TextBlock Foreground="Green"  Text="{Binding Chinese,StringFormat=成绩不错:{0}}"></TextBlock>
                    </DataTemplate>
                </local:CellDataTemplateSelector.template1>
                <local:CellDataTemplateSelector.template2>
                    <DataTemplate>
                        <TextBlock Foreground="Red"  Text="{Binding Chinese,StringFormat=还要努力:{0}}"></TextBlock>
                    </DataTemplate>
                </local:CellDataTemplateSelector.template2>
</local:CellDataTemplateSelector>

应用模板选择器

  <DataGridTemplateColumn   CellTemplateSelector="{StaticResource celldatatemplateselector}" Header="语文分数">  </DataGridTemplateColumn>

同样,它有着和样式选择器同样的缺点.

小结

    本文从简单到复杂介绍数据触发器,值转换器,样式选择器,模板选择器,它们有各自的应用场景,也有各自的局限性,在使用上要注意一下.最后,如果你有更好的建议,请不吝指教!

posted @ 2015-04-26 15:59  Caizl  阅读(5534)  评论(0编辑  收藏  举报