/// <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);
}
}