Enum Radio Button Binding
WPFのMVVMは好きです。他の言語で似非MVVM書いてるとなんだかなーって思う。
が、やっぱりWPFは嫌いです。
はい。EnumをBindingしたいとき。
まずおもむろにEnumの拡張を用意しましょう。このブログでも出てきたと思いますよー。
public static class EnumEx { public static string StringValue(this Enum e) { var fieldInfo = e.GetType().GetField(e.ToString()); var attribute = (StringValueAttribute)fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false).FirstOrDefault(); return attribute == null ? null : attribute.StringValue; } }
次にConverterを2つ用意しましょう。
using System; using System.Globalization; using System.Windows.Data; namespace Hoge { [ValueConversion(typeof(Enum), typeof(bool))] public class EnumToRadioButtonConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value.Equals(Enum.Parse(value.GetType(), parameter.ToString())); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (!(bool)value) return Binding.DoNothing; return Enum.Parse(targetType, parameter.ToString()); } } }
using System; using System.Globalization; using System.Windows.Data; namespace Hoge { [ValueConversion(typeof(Enum), typeof(string))] public class EnumToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (Enum.Parse(value.GetType(), parameter.ToString()) as Enum).StringValue(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (!(bool)value) return Binding.DoNothing; return Enum.Parse(targetType, parameter.ToString()); } } }
んで、enumとViewModel。双方向は省略。INotifyPropertyChangedを実装してくだされ。
namespace Hoge { public enum Gender { [StringValue("男性")] Male, [StringValue("女性")] Female } public sealed class HogeViewModel { public Gender Gender { get; set; } } }
で、View
<Page x:Class="Hoge.SamplePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Hoge" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="300"> <Page.DataContext> <local:HogeViewModel x:Name="viewModel" /> </Page.DataContext> <Page.Resources> <local:EnumToRadioButtonConverter x:Key="EnumToRadioButton"/> <local:EnumToStringConverter x:Key="EnumToString"/> </Page.Resources> <Grid> <StackPanel Orientation="Horizontal"> <RadioButton GroupName="Gender" Content="{Binding Gender, ConverterParameter=Male, Converter={StaticResource EnumToString}}" IsChecked="{Binding Gender, ConverterParameter=Male, Converter={StaticResource EnumToRadioButton}}"/> <RadioButton GroupName="Gender" Content="{Binding Gender, ConverterParameter=Female, Converter={StaticResource EnumToString}}" IsChecked="{Binding Gender, ConverterParameter=Female, Converter={StaticResource EnumToRadioButton}}"/> </StackPanel> </Grid> </base:BasePage>