WPF DataConverter 用の基底クラス

## データーコンバーター用の基底クラス

WPFを利用したアプリケーション開発をしていると、表示用のデーターコンバーターを
書く必要が出てきます。大抵は値をその名称である文字列に変換したり、`Visibility`や`Brush`に変える程度のことで、`ConvertBack`の必要もない些細なものですが、定義する数が多くなってくる（一つの`Window`で何個も必要になったりする）と何度も似たようなコードとか空の`ConvertBack`を書かなくてはならないのが面倒です。

ということで簡単なジェネリックな基底クラスを作って、そこから派生させることで手を抜いてます。

### クラス定義

```csharp: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に変換するコンバーター
```csharp: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 → 文字列用の基底クラスは別に作ってます。

### クラス定義

```csharp: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
}
```

### 例

```csharp: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];
    }
}
```