WPF转换器之通用转换器

摘要:
WPF中的转换器是一个非常好的数据类型转换解决方案,实用且功能强大。它的作用是将源数据转换为WPF本身所需的类型。它对数据实体没有攻击性,将经常在项目项目中使用。因此,掌握转换器是WPF开发的必要技能。

WPF中的转换器是一个非常好的数据类型转换解决方案,实用和强大, 它的作用是将源数据转换为WPF自身需要的类型,对数据实体没有侵略性,会在项目工程中频繁使用。所以掌握转换器是WPF开发的必备技能。

我刚接触转换器的时候,没有考虑通用性,每次遇到一个转换需求都会去创建一个新的转换器,久而久之,项目中的转换器已多如牛毛

WPF转换器之通用转换器第1张

这当然是我无法容忍的,我决定用一种通用转换器来代替绝大部分性质相同的转换操作,通过约定一套参数规则来适应不同的转换场景,达到转换器复用的目的。

转换器分为两种,IValueConverter(单值转换器)和IMultiValueConverter(多值转换器)

单值通用转换器 ObjectConverter

参数规则【比较值1|比较值2:true返回值:false返回值】

仔细一看,这个参数规则其实和三元表达式的含义相同,当源数据等于比较值1或者比较值2的时候,返回true返回值,否则返回false返回值

有了这个规则,就可以实现通用转换需求了,ObjectConverter源码如下

 public class ObjectConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string[] parray = parameter.ToString().ToLower().Split(':'); //将参数字符分段 parray[0]为比较值,parray[1]为true返回值,parray[2]为false返回值
            if (value == null)
                return parray[2];  //如果数据源为空,默认返回false返回值
            if (parray[0].Contains("|"))  //判断有多个比较值的情况
                return parray[0].Split('|').Contains(value.ToString().ToLower()) ? parray[1] : parray[2];  //多值比较
            return parray[0].Equals(value.ToString().ToLower()) ? parray[1] : parray[2];  //单值比较
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var returnValue = "otherValue";
            string[] parray = parameter.ToString().ToLower().Split(':');
            if (value == null)
                return returnValue;
            var valueStr = value.ToString().ToLower();
            if (valueStr != parray[1])
                return returnValue;
            else
                return parray[0].Contains('|') ? parray[0].Split('|')[0] : parray[0];
        }
    }

ObjectConverter的使用

1 <converter:ObjectConverter x:Key="objConverter"/>
2 
3 <Border Visibility="{Binding PanelStatus,  Converter={StaticResource objConverter},ConverterParameter=true:Visible:Collapsed}">
4 
5 <Border Background="{Binding BgColor,  Converter={StaticResource objConverter},ConverterParameter=1:Red:Blue}">
6 
7 <TextBlock Text="{Binding Type, Converter={StaticResource objConverter},ConverterParameter=1|2:VIP会员:普通会员}"/>

多值通用转换器 MultiObjectConverter

参数规则【各组比较值:比较条件(&amp;或|):true返回值:false返回值:返回值类型枚举】

多值转换器的参数规则略显麻烦,但是也和三元表达式类似,只不过多了比较条件和返回值枚举类型,这里有人要问了为什么单值转换器不需要声明返回值枚举而多值转换器需要,这是因为多值转换器的返回值不返回实际类型的话,返回类型会失效,WPF的默认转换器似乎没有起到作用。这个问题我也正在研究,所以先定义一个返回值枚举用来转换返回值的类型。姑且算一个临时解决方案吧

1 public classMultiObjectConverter : IMultiValueConverter
2 {
3         /// <summary>
4         ///多值转换器
5         /// </summary>
6         /// <param name="values">参数值数组</param>
7         /// <param name="parameter">
8         /// <para>参数</para>
9         /// <para>各组比较值:比较条件(&amp;或|):true返回值:false返回值:返回值类型枚举</para>
10         /// <para>v1;v2-1|v2-2;v3:&amp;:Visible:Collapsed:1</para>
11         /// </param>
12         /// <returns></returns>
13         public object Convert(object[] values, Type targetType, objectparameter, System.Globalization.CultureInfo culture)
14 {
15             string[] param = parameter.ToString().ToLower().Split(':');   //将参数字符串分段
16             string[] compareValues = param[0].Split(';'); //将比较值段分割为数组
17             if (values.Length != compareValues.Length)  //比较源数据和比较参数个数是否一致
18                 return ConvertValue(param[3], param[4]);
19             var trueCount = 0; //满足条件的结果数量
20             var currentValue = string.Empty;
21             IList<string> currentParamArray = null;
22             for (var i = 0; i < values.Length; i++)
23 {
24                 currentValue = values[i] != null ? values[i].ToString().ToLower() : string.Empty;
25                 if (compareValues[i].Contains("|"))
26 {
27                     //当前比较值段包含多个比较值
28                     currentParamArray = compareValues[i].Split('|'); 
29                     trueCount += currentParamArray.Contains(currentValue) ? 1 : 0;  //满足条件,结果+1
30 }
31                 else
32 {
33                     trueCount += compareValues[i].Equals(currentValue) ? 1 : 0;  //满足条件,结果+1
34 }
35 }
36             currentParamArray = null;
37             currentValue = string.Empty;
38             var compareResult = param[1].Equals("&") ?
39                 trueCount ==values.Length :
40                 trueCount > 0;   //判断比较结果
41             return ConvertValue(compareResult ? param[2] : param[3], param[4]);
42 }
43 
44         public object[] ConvertBack(object value, Type[] targetTypes, objectparameter, System.Globalization.CultureInfo culture)
45 {
46             throw newNotImplementedException();
47 }
48 
49         private object ConvertValue(string result, stringenumStr)
50 {
51             var convertResult = (ConvertResult)int.Parse(enumStr);
52             if (convertResult ==ConvertResult.显示类型)
53                 return result.Equals("collapsed") ?Visibility.Collapsed : Visibility.Visible;
54             if (convertResult ==ConvertResult.布尔类型)
55                 returnSystem.Convert.ToBoolean(result);
56             return null;  //后续自行扩展
57 }
58 
59         private enumConvertResult
60 {
61             显示类型 = 1,
62             布尔类型 = 2,
63             字符串类型 = 3,
64             整型 = 4,
65             小数型 = 5,
66             画刷类型 = 6,
67             样式类型 = 7,
68             模板类型 = 8
69 }
70     }

MulitObjectConverter的使用

1 <TextBlock Text="test">
2    <TextBlock.Visibility>
3         <MultiBinding Converter="{StaticResource mobjConverter}"
4 ConverterParameter="1|2;true:|:Visible:Collapsed:1">
5              <Binding Path="Filed1"/>
6              <Binding Path="Filed2"/>
7         </MultiBinding>
8     </TextBlock.Visibility>
9 </TextBlock>    

单值通用转换器和多值通用转换器已经讲完了,读者可以根据自己的需求定制ConverterParameter的规则,实现灵活扩展。欢迎入群交流372754241

免责声明:文章转载自《WPF转换器之通用转换器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java实现BASE64编解码器Python实现一些常用排序算法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WPF自定义窗口(Windows Server 2012 Style)

先上图 新建CustomControl,名:HeaderedWindow ThemesGeneric.aml文件夹下加入 笔刷,转换器 1 <SolidColorBrush x:Key="ActiveBackground" Color="#FF66CBEA"/> 2 <SolidColorBrush x:Key="De...

WPF实现TextBox水印效果

通常情况下,在使用文本框的时候,一般会在文本框上放一段水印文字,今天用WPF来实现一下 创建一个用户控件 一般像这种常用的,最好是自己写成用户控件,防止复制粘贴大量冗余代码 XAML: <TextBox x: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prese...

python- generator生成器

什么是生成器? 通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的l...

WPF控件

什么是控件 WPF中是数据驱动UI,数据是核心、是主动的;UI从属与数据并表达数据、是被动的。UI的功能是让用户观察和操作数据,为了让用户观察数据,我们需要用UI元素来显示数据;为了让用户操作数据,我们需要用UI元素响应用户的操作。WPF中把那些能够显示数据、响应用户操作的UI元素称为控件。 控件所显示的数据,我们称之为“数据内容”,控件在响应用户的操作后...

WPF 多语言解决方案

1、首先安装Multilingual App Toolkit 2、新建项目,在VS中点击"工具" -> "Multilingual App Toolkit" -> "启用选定内容" 如果出现上述Issue, 打开项目AssemblyInfo.cs文件,加入如下代码片段,然后重复Step 2. [assembly: NeutralRes...

java执行linux shell命令,并拿到返回值

1 packagecom.pasier.xxx.util; 2 3 importjava.io.IOException; 4 importjava.io.InputStream; 5 importjava.nio.charset.Charset; 6 7 importorg.slf4j.Logger; 8 importorg.slf4j.LoggerF...