次のような列挙型があります:
public enum MyLovelyEnum
{
FirstSelection,
TheOtherSelection,
YetAnotherOne
};
DataContext にプロパティができました:
public MyLovelyEnum VeryLovelyEnum { get; set; }
そして、WPF クライアントに 3 つの RadioButton が作成されました。
<RadioButton Margin="3">First Selection</RadioButton>
<RadioButton Margin="3">The Other Selection</RadioButton>
<RadioButton Margin="3">Yet Another one</RadioButton>
では、適切な双方向バインディングのために RadioButtons をプロパティにバインドするにはどうすればよいでしょうか?
ベストアンサー1
受け入れられた回答をさらに簡略化できます。列挙型を xaml で文字列として入力し、コンバーターで必要以上の作業を行う代わりに、文字列表現ではなく列挙型の値を明示的に渡すことができます。CrimsonX がコメントしたように、エラーは実行時ではなくコンパイル時にスローされます。
コンバータパラメータ={x:Static local:YourEnumType.Enum1}
<StackPanel>
<StackPanel.Resources>
<local:ComparisonConverter x:Key="ComparisonConverter" />
</StackPanel.Resources>
<RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum1}}" />
<RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum2}}" />
</StackPanel>
次にコンバーターを簡略化します。
public class ComparisonConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value?.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value?.Equals(true) == true ? parameter : Binding.DoNothing;
}
}
編集 (2010 年 12 月 16 日):
匿名さんに感謝示唆するDependencyProperty.UnsetValue ではなく Binding.DoNothing を返します。
注 - 同じコンテナー内の RadioButton の複数のグループ (2011 年 2 月 17 日):
xaml では、ラジオ ボタンが同じ親コンテナーを共有している場合、1 つを選択すると、そのコンテナー内の他のすべてのラジオ ボタンの選択が解除されます (別のプロパティにバインドされている場合でも)。したがって、共通のプロパティにバインドされているラジオ ボタンは、スタック パネルのように独自のコンテナーにグループ化するようにしてください。関連するラジオ ボタンが単一の親コンテナーを共有できない場合は、各ラジオ ボタンの GroupName プロパティを共通の値に設定して、それらを論理的にグループ化します。編集 (2011 年 4 月 5 日):
ConvertBack の if-else を三項演算子を使用するように簡略化しました。注 - クラス内にネストされた列挙型 (2011 年 4 月 28 日):
列挙型がクラス内にネストされている場合 (名前空間内に直接ではなく)、質問に対する (マークされていない) 回答に記載されているように、XAML で列挙型にアクセスするために '+' 構文を使用できる場合があります。ConverterParameter={x:Static local: YourClass+ YourNestedEnumType.Enum1}
これによるとMicrosoft Connect の問題ただし、VS2010 のデザイナーは と表示してロードしなくなります"Type 'local:YourClass+YourNestedEnumType' was not found."
が、プロジェクトは正常にコンパイルおよび実行されます。もちろん、列挙型を名前空間に直接移動できれば、この問題を回避できます。
編集 (2012 年 1 月 27 日):
Enum フラグを使用する場合、コンバーターは次のようになります。public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((Enum)value).HasFlag((Enum)parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}
編集(2015年5月7日):
Nullable Enum の場合 (質問では **尋ねられていません** が、場合によっては必要になることがあります。たとえば、ORM が DB から null を返す場合や、プログラム ロジックで値が提供されないことが理にかなっている場合など)、Convert メソッドに最初の null チェックを追加し、適切な bool 値 (通常は false です (ラジオ ボタンを選択しない場合)) を返すことを忘れないでください。次のようになります。 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) {
return false; // or return parameter.Equals(YourEnumType.SomeDefaultValue);
}
return value.Equals(parameter);
}