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

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

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

转换器分为两种,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的使用

 <converter:ObjectConverter x:Key="objConverter"/>

 <Border Visibility="{Binding PanelStatus,  Converter={StaticResource objConverter},ConverterParameter=true:Visible:Collapsed}">

 <Border Background="{Binding BgColor,  Converter={StaticResource objConverter},ConverterParameter=1:Red:Blue}">

 <TextBlock Text="{Binding Type, Converter={StaticResource objConverter},ConverterParameter=1|2:VIP会员:普通会员}"/>

多值通用转换器 MultiObjectConverter

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

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

 public class MultiObjectConverter : IMultiValueConverter
{
/// <summary>
/// 多值转换器
/// </summary>
/// <param name="values">参数值数组</param>
/// <param name="parameter">
/// <para>参数</para>
/// <para>各组比较值:比较条件(&amp;或|):true返回值:false返回值:返回值类型枚举</para>
/// <para>v1;v2-1|v2-2;v3:&amp;:Visible:Collapsed:1</para>
/// </param>
/// <returns></returns>
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string[] param = parameter.ToString().ToLower().Split(':'); //将参数字符串分段
string[] compareValues = param[].Split(';'); //将比较值段分割为数组
if (values.Length != compareValues.Length) //比较源数据和比较参数个数是否一致
return ConvertValue(param[], param[]);
var trueCount = ; //满足条件的结果数量
var currentValue = string.Empty;
IList<string> currentParamArray = null;
for (var i = ; i < values.Length; i++)
{
currentValue = values[i] != null ? values[i].ToString().ToLower() : string.Empty;
if (compareValues[i].Contains("|"))
{
//当前比较值段包含多个比较值
currentParamArray = compareValues[i].Split('|');
trueCount += currentParamArray.Contains(currentValue) ? : ; //满足条件,结果+1
}
else
{
trueCount += compareValues[i].Equals(currentValue) ? : ; //满足条件,结果+1
}
}
currentParamArray = null;
currentValue = string.Empty;
var compareResult = param[].Equals("&") ?
trueCount == values.Length :
trueCount > ; //判断比较结果
return ConvertValue(compareResult ? param[] : param[], param[]);
} public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
} private object ConvertValue(string result, string enumStr)
{
var convertResult = (ConvertResult)int.Parse(enumStr);
if (convertResult == ConvertResult.显示类型)
return result.Equals("collapsed") ? Visibility.Collapsed : Visibility.Visible;
if (convertResult == ConvertResult.布尔类型)
return System.Convert.ToBoolean(result);
return null; //后续自行扩展
} private enum ConvertResult
{
显示类型 = ,
布尔类型 = ,
字符串类型 = ,
整型 = ,
小数型 = ,
画刷类型 = ,
样式类型 = ,
模板类型 =
}
}

MulitObjectConverter的使用

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

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

WPF转换器之通用转换器的更多相关文章

  1. WPF转换器之值转换器

    WPF有两转转换器,一种是值转换器,另一种多值转换器,在开发过程中经常会从数据拉一些数据过来,比如存储性别的时候往往会用0或1,但在界面上肯定是要显示男或女,那么这个时候就可以用上值转换器 编写转换器 ...

  2. pdf转换成word转换器免费版

    在平时的办公中,我们只需要有一款比较好用的pdf转换成word转换器,就能提高我们的工作效率,但是国内外的pdf转换成word转换器应该怎么选呢?小编因为是文职工作者,所以在日常的实践中选出了ABBY ...

  3. [No000012C]WPF(4/7)类型转换器和标记扩展[译]

    介绍 之前讨论了WPF的基础架构,然后逐步开始学习布局面板,转换,介绍了不同的控件,容器,UI转换等.在这篇文章中,我将讨论每个创建XAML应用前的开发人员应该了解的关于XAML最重要的东西. 标记扩 ...

  4. ES6转换器之Babel

    ES6部分功能没有支持,所以想学习ES6,得先有个转换器,就是将ES6的代码转换为ES5. 我这里用的是Gulp + Bable的形式来将ES6转换为ES5的. 前提: (1).Gulp和Bable都 ...

  5. WPF报表自定义通用可筛选列头-WPF特工队内部资料

    由于项目需要制作一个可通用的报表多行标题,且可实现各种类型的内容显示,包括文本.输入框.下拉框.多选框等(自定的显示内容可自行扩展),并支持参数绑定转换,效果如下: 源码结构 ColumnItem类: ...

  6. mybatis枚举自动转换(通用转换处理器实现)

    https://blog.csdn.net/fighterandknight/article/details/51520595 https://blog.csdn.net/fighterandknig ...

  7. WPF Binding的值转换器

    注意:值转换器中用于传入额外信息的参数 parameter 在 Binding 时使用 Binding 对象的 ConverterParameter 属性指定,但是设置了 ConverterParam ...

  8. springboot整合mongodb问题1-Decimal128和BigDecimal的转换之mongodb转换器使用(转)

    转自:https://blog.csdn.net/weixin_41792559/article/details/79575524 1.Decimal128的了解由于mongodb4.3以上新加了De ...

  9. 在spring data jpa中使用自定义转换器之使用枚举转换

    转载请注明http://www.cnblogs.com/majianming/p/8553217.html 在项目中,经常会出现这样的情况,一个实体的字段名是枚举类型的 我们在把它存放到数据库中是需要 ...

随机推荐

  1. 用Backtrack进行渗透测试评估

    Web应用程序的分析在渗透测试和漏洞评估中发挥了重要的作用.确定Web应用程序的正确信息(例如使用的插件,CMS类型等)都可以帮助测试者使用准确的漏洞来测试,能够降低整个渗透测试漏洞评估所花费的时间. ...

  2. 安装python2.7

    系统的yum程序使用的是python2.6,不能够卸载系统所带的python环境.python2.7的安装命令如下 tar vjxf Python-2.7.1.tar.bz2 cd Python-2. ...

  3. 第一次接触Axure

    现在已经是凌晨4:21了,我的第一份Axure.RP文件终于接近尾声,我带着些许疲倦些许兴奋的状态写下这篇博客,记录我和Axure的初遇.       三天前,我加入了湖南大学金山俱乐部,参加了第一次 ...

  4. javascript中apply,call,bind区别,bind兼容等问题总结

    1 三者的相似之处: (1).都是用来改变函数的this对象的指向的 (2).都是用第一个参数来做this对象的指向 (3).都可以传参数进去 那么,具体到它们有什么区别呢?请看下面的例子: 两个对象 ...

  5. js验证input是否输入数字

    onkeyup="if(isNaN(value))execCommand('undo')" onafterpaste="if(isNaN(value))execComma ...

  6. jquery删除表格行

    $(".mingxirmspan").click(function(){ $(this).closest("tr").remove(); })

  7. SOD开源框架MSF(消息服务框架)进阶篇

    复习:在上一篇我介绍了MSF的基本订阅,模式就是,客户端A,订阅服务器.客户端B,订阅服务器.通过服务器广播消息, 所有订阅过的客户端都能接到消息. 进阶:在上一篇的基础上,增加客户端A,发送信息到服 ...

  8. thinkphp带查询条件的分页

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  9. PHP实现简单的评论与回复功能还有删除信息

    我们首先先看一下功能 上面黑色的是评论的下面红色的字体是回复的 再来看看怎么实现的 1.发布评论 <form action="pinglunchili.php" method ...

  10. WdatePicker文本框显示当前日期和时间限制<My97DatePicker两个日期范围不超过30天,第一个小于第二个,都不大于当前日期 >

    My97DatePicker是很不错的一个日期选择插件,体积只有几十k但是功能非常强大.官网:http://www.my97.net/ 能满足很多苛刻的要求. WdatePicker文本框显示当前日期 ...