zoukankan      html  css  js  c++  java
  • 如何通过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"];


    不知各位有没有更方便的方法?或者网络上早已有正解~~~~
  • 相关阅读:
    设计模式4---策略模式
    设计模式3---抽象工厂模式
    209. Minimum Size Subarray Sum(双指针)
    174. Dungeon Game(动态规划)
    二分查找
    74. Search a 2D Matrix(二分查找,剑指offer 1)
    81. Search in Rotated Sorted Array II
    33. Search in Rotated Sorted Array(二分查找)
    34. Search for a Range (二分查找)
    35. Search Insert Position(二分查找)
  • 原文地址:https://www.cnblogs.com/Sunpire/p/1712248.html
Copyright © 2011-2022 走看看