データーコンバーター用の基底クラス
WPFを利用したアプリケーション開発をしていると、表示用のデーターコンバーターを
書く必要が出てきます。大抵は値をその名称である文字列に変換したり、Visibility
やBrush
に変える程度のことで、ConvertBack
の必要もない些細なものですが、定義する数が多くなってくる(一つのWindow
で何個も必要になったりする)と何度も似たようなコードとか空のConvertBack
を書かなくてはならないのが面倒です。
ということで簡単なジェネリックな基底クラスを作って、そこから派生させることで手を抜いてます。
クラス定義
DataConverterBase.cs
/// <summary>
/// データーコンバーター用の基底クラス
/// </summary>
/// <typeparam name="T1">入力値の型</typeparam>
/// <typeparam name="T2">出力値の型</typeparam>
public class DataConverterBase<T1, T2> : IValueConverter
{
#region **** Delegates
protected Func<T1, T2> Convert;
protected Func<T2, T1> ConvertBack;
#endregion
#region **** Method : IValueConverter.Convert
/// <summary>
/// IValueConverter.Convertの実装
/// </summary>
/// <param name="value">object</param>
/// <param name="targetType">Type</param>
/// <param name="parameter">object</param>
/// <param name="culture">CultureInfo</param>
/// <returns>object</returns>
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (Convert != null) ? Convert((T1)value) : value;
}
#endregion
#region **** Method : IValueConverter.ConvertBack
/// <summary>
/// IValueConverter.ConvertBackの実装
/// </summary>
/// <param name="value">object</param>
/// <param name="targetType">Type</param>
/// <param name="parameter">object</param>
/// <param name="culture">CultureInfo</param>
/// <returns>object</returns>
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (ConvertBack != null) ? ConvertBack((T2)value) : value;
}
#endregion
}
変換処理の実体をデリゲートにして派生クラスで設定するという仕様になっています。
デリゲートが設定されていない場合はそのままの値を返すようになっているので、ConvertBack
が必要ない場合は何も書かなくても良いようにしています。
例:Bool値をVisibilityに変換するコンバーター
Bool2VisibilityConverter.cs
[ValueConversion(typeof(bool), typeof(Visibility))]
public class Bool2VisibilityConverter : DataConverterBase<bool,Visibility>
{
public Bool2VisibilityConverter ()
{
Converter = v => ((bool)v) ? Visibility.Visible : Visibility.Hidden;
}
}
Enum用のデーターコンバーター
あと区分などで利用している enum の値を表示用の文字列に変換するデーターコンバーターが必要になるケースがとくに多いので、enum → 文字列用の基底クラスは別に作ってます。
クラス定義
Enum2StingConverter.cs
/// <summary>
/// Enum用のデーターコンバーター
/// </summary>
/// <typeparam name="T">型</typeparam>
public abstract class Enum2StingConverter<T> : IValueConverter
{
#region *** Virtual Method : Enum2String
/// <summary>
/// Enumを文字列にする
/// </summary>
/// <param name="e">T</param>
/// <returns>string</returns>
protected virtual string Enum2String(T e)
{
return e.ToString();
}
#endregion
#region **** Method : Convert
/// <summary>
/// T -> string
/// </summary>
/// <param name="value">object</param>
/// <param name="targetType">Type</param>
/// <param name="parameter">object</param>
/// <param name="culture">CultureInfo</param>
/// <returns>object</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum2String((T)value);
}
#endregion
#region **** Method : ConvertBack
/// <summary>
/// string -> T
/// </summary>
/// <param name="value">object</param>
/// <param name="targetType">Type</param>
/// <param name="parameter">object</param>
/// <param name="culture">CultureInfo</param>
/// <returns>object</returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
foreach (var n in Enum.GetValues(typeof(T)))
{
if (Enum2String((T)n) == (string)value)
return (T)n;
}
throw new ArgumentException();
}
#endregion
}
例
Gender2StringConverter.cs
// 性別
public enum Gender { Unkown, Male, Female }
[ValueConversion(typeof(Gender), typeof(String))]
public class Gender2StringConverter : Enum2StingConverter<Gender>
{
protected override string Enum2String(STStudyStatus e)
{
string names[] = { "不明", "男性", "女性" };
return names[(int)e];
}
}