しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

UWP で列挙型の値をラジオボタンにバインドしたい

ラジオボタンで下記のような選択肢を作ろうと思います

f:id:matatabi_ux:20150923230930p:plain

・・・既定の列挙型である HorizontalAlifnment を ViewModel のプロパティに保持したい場合、XAML の方はどうすればよいでしょうか


というわけで用意したのが下記の Converter

/// <summary>
/// Enum to bool converter
/// </summary>
public class EnumToBoolConverter : IValueConverter
{
    /// <summary>
    /// Enum type
    /// </summary>
    public Type EnumType { get; set; }

    /// <summary>
    /// Convert Enum to bool 
    /// </summary>
    /// <param name="value">Enum value</param>
    /// <param name="targetType">target type</param>
    /// <param name="parameter">parameter</param>
    /// <param name="language">language</param>
    /// <returns>bool</returns>
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null)
        {
            return false;
        }
        return value == parameter || Enum.GetName(this.EnumType, value).Equals(parameter) ;
    }

    /// <summary>
    /// Convert bool to Enum 
    /// </summary>
    /// <param name="value">bool value</param>
    /// <param name="targetType">target type</param>
    /// <param name="parameter">parameter</param>
    /// <param name="language">language</param>
    /// <returns>Enum</returns>
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        var boolean = value as bool?;
        if (boolean != null && boolean.HasValue && boolean.Value)
        {
            try
            {
                return Enum.Parse(this.EnumType, parameter.ToString());
            }
            catch (Exception)
            {
            }
        }
        return DependencyProperty.UnsetValue;
    }
}

プロパティにバインドする列挙型の型を指定し、パラメーターにバインドするラジオボタンに割り当てる列挙値を指定する Converter です

次のような XAML で記述します

<StackPanel Orientation="Horizontal"
            Margin="20,10,0,0">
    <RadioButton Content="左寄せ"
                 GroupName="HorizontalAlignment">
        <RadioButton.IsChecked>
            <Binding Path="HorizontalAlignment"
                     Mode="TwoWay"
                     ConverterParameter="Left">
                <Binding.Converter>
                    <cv:EnumToBoolConverter EnumType="ux:HorizontalAlignment"/>
                </Binding.Converter>
            </Binding>
        </RadioButton.IsChecked>
    </RadioButton>
    <RadioButton Content="中央寄せ"
                 GroupName="HorizontalAlignment">
        <RadioButton.IsChecked>
            <Binding Path="HorizontalAlignment"
                     Mode="TwoWay"
                     ConverterParameter="Center">
                <Binding.Converter>
                    <cv:EnumToBoolConverter EnumType="ux:HorizontalAlignment"/>
                </Binding.Converter>
            </Binding>
        </RadioButton.IsChecked>
    </RadioButton>
    <RadioButton Content="右寄せ"
                 GroupName="HorizontalAlignment">
        <RadioButton.IsChecked>
            <Binding Path="HorizontalAlignment"
                     Mode="TwoWay"
                     ConverterParameter="Right">
                <Binding.Converter>
                    <cv:EnumToBoolConverter EnumType="ux:HorizontalAlignment"/>
                </Binding.Converter>
            </Binding>
        </RadioButton.IsChecked>
    </RadioButton>
</StackPanel>

Enum.GetName() で列挙型の名称、Enum.Parse() で文字列から列挙型値への変換ができるため上記のような記述で双方向バインディングができました

択一の UI ならラジオボタン以外にも応用できると思います