RadioButtons を enum にバインドするにはどうすればいいですか? 質問する

RadioButtons を enum にバインドするにはどうすればいいですか? 質問する

次のような列挙型があります:

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);
    }

注 - NullReferenceException (2018 年 10 月 10 日):

例を更新して、NullReferenceException をスローする可能性を排除しました。`IsChecked` は null 許容型なので、`Nullable` を返すのが妥当な解決策と思われます。

おすすめ記事