天天看點

WPF-通用轉換器

/// <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 if (sourceType == typeof(int) && Alias != null)
                    {
                        return Enum.Parse(targetType, Alias[value], false);
                    }
                    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);
        }
    }
           

繼續閱讀