wpf常用类型转换器,支持基元类型、可空基元类型、枚举

分享一个常用类型转换器,类名是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);
    }
}

 

posted @ 2020-09-25 17:12  孤独成派  阅读(265)  评论(0编辑  收藏  举报