分享一个常用类型转换器,类名是GenericTypeConverter,一开始并不是我写的,但是经过长时间的磨合,变得更加完善和简洁了;
下面给出几个使用示例:
Visibility="{Binding Converter={StaticResource genericTypeConverter},ConverterParameter='True:Visible|False:Collapsed'}"
IsChecked="{Binding Converter={StaticResource genericTypeConverter},ConverterParameter='0:True|other:False'}"
Text="{Binding Converter={StaticResource genericTypeConverter},ConverterParameter='0:开发者Key|1:证书签名'}"
规格是以“|”分成几个键值对,other表示其他值,支持双向绑定,但一般不常用;
下面分享代码:
public sealed class GenericTypeConverter : IValueConverter { /// <summary> /// 正向键值对字典 /// </summary> private Dictionary<String, String> Alias { get; set; } /// <summary> /// 反向键值对字典 /// </summary> private Dictionary<String, String> BackAlias { get; set; } private String aliasStrTemp; /// <summary> /// 解析转换规则 /// </summary> /// <param name="aliasStr">规则字符串</param> private void ParseAliasByStr (String aliasStr) { if (aliasStrTemp == aliasStr) { //避免再次解析 return; } aliasStrTemp = aliasStr; Alias = new Dictionary<String, String> (); BackAlias = new Dictionary<String, String> (); String[] kvs = aliasStr.Split ('|'); foreach (String item in kvs) { var index = item.IndexOf (':'); if (index == -1) continue; var key = item.Substring (0, index); var value = item.Substring (index + 1); if (!String.Equals (key, "other", StringComparison.Ordinal)) { if (!BackAlias.ContainsKey (value)) BackAlias.Add (value, key); } Alias.Add (key, value); } } private Object ConvertCommon (Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture, Boolean isBack) { var arg = parameter as String; if (String.IsNullOrWhiteSpace (arg)) return Binding.DoNothing; ParseAliasByStr (arg); Dictionary<String, String> alias; if (isBack) alias = BackAlias; else alias = Alias; //绑定的值 String bindingValue = value?.ToString () ?? String.Empty; if (alias.ContainsKey (bindingValue)) return alias[bindingValue].ChangeType (targetType); else if (alias.ContainsKey ("other")) return alias["other"].ChangeType (targetType); return Binding.DoNothing; } public Object Convert (Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture) { return ConvertCommon (value, targetType, parameter, culture, false); } public Object ConvertBack (Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture) { return ConvertCommon (value, targetType, parameter, culture, true); } }
需要用到一个扩展方法ChangeType,扩展类如下:
public static class ObjectExtension { /// <summary> /// 尝试转换类型,若失败,则返回默认值 /// 警告:因包含try catch,且考虑类型多,效率极低 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> public static Boolean TryChangeType<T> (this Object obj, out T t) { var type = typeof (T); try { t = (T) obj.ChangeType (type); return true; } catch { t = default (T); return false; } } public static Object ChangeType (this Object obj, Type targetType) { if (obj == null) return null; var sourtType = obj.GetType (); if (sourtType == targetType) return obj; if (targetType.IsEnum) return Enum.Parse (targetType, obj.ToString ()); if (targetType.IsGenericType && targetType.GetGenericTypeDefinition () == typeof (Nullable<>)) targetType = targetType.GetGenericArguments () [0]; return Convert.ChangeType (obj, targetType); } public static T ChangeType<T> (this Object obj) { var type = typeof (T); if (obj == null) return default (T); return (T) ChangeType (obj, type); } }