WPF值通用的类型转换器详解(转)

摘要:
http://www.dxysoft.com/article/html/4005.html在WPF中应用数据绑定时,通常需要进行一些简单的逻辑判断。例如,ViewModel中有一个HasError(布尔值)属性来指示是否存在错误。我需要将它绑定到Button的IsEnable属性,也就是说,当没有错误时,Button是可用的。此时,您需要反转HasError。不支持WPF的默认绑定引擎。还有另一种情况,如视图

http://www.dxysoft.com/article/html/4005.html

在WPF中应用数据绑定时经常需要做一些简单的逻辑判断。比如ViewModel中有一个HasError(布尔值)的属性表示是否有错误。我需要将它绑定于Button的IsEnable属性上,即:当没有错误时Button可用。

这时就需要将HasError取反。WPF默认的绑定引擎是不支持的。还有一种情况比如ViewModel中有一个Sex(int值)的属性表示性别,我需要将它绑定到TextBlock上,当值为1时显示男,值为2时显示女。WPF默认绑定也是不支持这种判断的。于是一个通用的值转换器就诞生了,用法如下:

<Button IsEnabled="{Binding HasError, Converter={StaticResource GenericTypeConverter}, ConverterParameter='IsReverse=True'}">OK</Button>

IsReverse参数表示是否取返,如果转换的值为true则变为false,反之亦然。

<TextBlock Text="{Binding Sex, Converter={StaticResource GenericTypeConverter}, ConverterParameter='Alias=1:男|2:女|other:未知'}" />

Alias参数表示将值映射为字符串,other表示当遇到没有指定的值时显示的文本

另外bool to Visibility的转换可以自动进行,不需要指定参数。

有意见欢迎指正

完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;

namespace MoodSunshiny.WPF.Converter
{
/// <summary>
/// 一个通用的类型转换器,可以提供更多转换控制参数
/// </summary>
public class GenericTypeConverter : IValueConverter
{
/// <summary>
/// 是否反转转换源参数值
/// 仅对bool类型的值有效
/// </summary>
private bool IsReverse { get; set; }

/// <summary>
/// 用于将转换结果映射为其它字符串
/// 例如:Alias=True:是|False:否
/// </summary>
private Dictionary<object, string> Alias { get; set; }

/// <summary>
/// 解析转换参数
/// </summary>
private void AnalyseConvertParameter(string convertParameter)
{
/*设置参数默认值*/
IsReverse = false;
Alias = null;

if (!string.IsNullOrEmpty(convertParameter))
{
var pkvs = convertParameter.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var pkv in pkvs)
{
var pkvo = pkv.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
if (pkvo.Length != 2)
throw new NotSupportedException("不支持设置:" + pkv);
var pk = pkvo[0].Trim();
var pv = pkvo[1].Trim();

switch (pk)
{
case "IsReverse":
bool b;
if (!bool.TryParse(pv, out b))
throw new NotSupportedException("参数取值错误:" + pkv);
else
IsReverse = b;
break;
case "Alias":
{
Alias = new Dictionary<object, string>();
var dfkvs = pv.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var dfkv in dfkvs)
{
var dfkvo = dfkv.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (dfkvo.Length != 2)
throw new NotSupportedException("不支持设置:" + dfkvo);
var dfk = dfkvo[0].Trim();
var dfv = dfkvo[1].Trim();

object oKey = null;
int i;
if (dfk.Equals("true", StringComparison.OrdinalIgnoreCase))
oKey = true;
else if (dfk.Equals("false", StringComparison.OrdinalIgnoreCase))
oKey = false;
else if (dfk.Equals("other", StringComparison.OrdinalIgnoreCase))
oKey = "other";
else if (int.TryParse(dfk, out i))
oKey = i;
else
throw new NotSupportedException("参数取值错误:" + dfkv);

Alias[oKey] = dfv;
}
}
break;
default:
throw new NotSupportedException("不支持的参数名:" + pk);
}
}
}
}

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
AnalyseConvertParameter(parameter as string);

try
{
var sourceType = value.GetType();
if (IsReverse && sourceType == typeof(bool))
value = !((bool)value);

if (targetType == typeof(string))
{
if (Alias != null && Alias.ContainsKey(value))
return Alias[value];
else if (Alias != null && Alias.ContainsKey("other"))
return Alias["other"];
else
return value == null ? "" : value.ToString();
}
if (targetType == typeof(bool))
{
if (sourceType == typeof(Visibility))
return (Visibility)value == Visibility.Visible;
}
else if (targetType.IsEnum)
{
if (sourceType == typeof(bool) && targetType == typeof(Visibility))
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
else
{
return Enum.Parse(targetType, value.ToString(), true);
}
}
else
{
return System.Convert.ChangeType(value, targetType);
}

return System.Convert.ChangeType(value, targetType);
}
catch
{
return null;
}
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
}
}


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

上篇Xcode Provisioning Profile Expires 证书过期无法真机调试Navicat for SQLite常用功能学习(01)下篇

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

相关文章

ASP.NET Web API 2系列(一):初识Web API及手动搭建基本框架

 1.导言 随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数。全栈工程师的压力越来越大。 PC端,pad端,移动端App(安卓/IOS)的发展,使得前后端一体的开发模式十分笨重。因此,前后端分离是web发展的趋势,其中,RESTful API是目前前后端分离的最佳实践,ASP.NET Web API是在.NET Framework上构建RES...

WPF中设置TEXTBOX为多行文本输入框

WPF中没有textarea的东西,不像在ASP.NET中设置textbox那样设置一个多行属性就可以变成文本域,虽然可以使用ricktextbox实现多行文本输入,但是richtextbox比较复杂,面对简单的多行文本输入的时候太麻烦了点,但是WPF的textbox依然可以通过设置属性实现像textarea一样的多行文本输入。 一下是转载的一篇出处。 本...

WPF默认控件模板的获取和资源词典的使用

一、获取默认的控件模板WPF修改控件模板是修改外观最方便的方式,但是会出现不知道原来的控件的模板长什么样,或者想用来参考的,下面分享一下获取某控件默认控件模板的方式(已Button为例): 1、创建一个Button 2、在界面上选择Button,右键->编辑模板->编辑副本 ,即可看到XAML中自动生成了原始的控件模板 3、可以在默认模板上修改...

前端必备的js知识点(转载)

1、本文主体源自:http://www.cnblogs.com/coco1s/p/4029708.html,有兴趣的可以直接去那里看,也可以看看我整理加拓展的。2、js是一门什么样的语言及特点?        js是一种基于对象和事件驱动的并具有相对安全性的客户端脚本语言。也是一种广泛用于web客户端开发的脚本语言,常用来给html网页添加动态功能,如响应...

WPF设置软件界面背景为MediaElement并播放视频

在我们的常见的软件界面设计中我们经常会设置软件的背景为SolidColorBrush或者LinerColorBrush、RadialGradientBrush等一系列的颜色画刷为背景,有时我们也会使用ImageBrush添加图片来作为界面的背景,另外常用的还有DrawingBrush以及今天需要进行总结的VisualBrush,这些我们都是比较容易实现的,...

VS编程,WPF中,关于TextBlock与TextBox 控件文本垂直居中或者水平居中的说明

有时为了显示的美观性,需要将文本控件中的文字垂直或者水平居中,这里说明一下需要注意的地方。 1、对于指定了长、宽的区域,用TextBox实现文本居中例如:一个长400,高100的文本框,要实现文字居中 <TextBox FontSize="36"Width=" 400"Height=" 100"HorizontalContentAlignment="...