チェックボックス付きのブール型のプロパティがあります。
値をtrue/falseにする同じプロパティにバインドする2つのラジオボタンに変更したいです。
どうすればそれができますか?
<RadioButton GroupName="Group1"
IsChecked="{Binding PropertyValue}" Content="Yes" />
<RadioButton GroupName="Group1" Content="No"
IsChecked="{Binding PropertyValue,
Converter={StaticResource BoolInverterConverter}}" />
public class BoolInverterConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value is bool)
{
return !(bool)value;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value is bool)
{
return !(bool)value;
}
return value;
}
#endregion
}
標準のバインディングアプローチには、UIが読み込まれるたびにバインディングセッターが「選択されていない」として起動されるという不幸な副作用があります。そのため、boolのセッターでユーザーのクリックを処理するコードがある場合、「true」boolにバインドしていても、セッターを「false」に起動するなどの奇妙なことを行います。
ラジオボタン専用のコンバーターでこれを回避しました。
public class BoolRadioConverter : IValueConverter
{
public bool Inverse { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool boolValue = (bool) value;
return this.Inverse ? !boolValue : boolValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool boolValue = (bool)value;
if (!boolValue)
{
// We only care when the user clicks a radio button to select it.
return null;
}
return !this.Inverse;
}
}
リソース内:
<converters:BoolRadioConverter x:Key="BoolRadioConverter" />
<converters:BoolRadioConverter x:Key="InverseBoolRadioConverter" Inverse="True" />
あなたのxamlで:
<RadioButton
Content="True option"
GroupName="radioGroup1"
IsChecked="{Binding MyProperty,
Converter={StaticResource BoolRadioConverter}}" />
<RadioButton
Content="False option"
GroupName="radioGroup2"
IsChecked="{Binding MyProperty,
Converter={StaticResource InverseBoolRadioConverter}}" />
ブール値を元に戻す値コンバーターを使用できます。
そのコンバーターで、コンバーターなしで1つのCheckbox.IsChecked-propertyをブール値にバインドし、コンバーターで1つのCheckBox.IsChecked-propertyをバインドします。これでうまくいくはずです。
ここにそのようなコンバータのコードがあります。 here からコピーして、コードを数行追加しました。そこに詳細情報があります。
public class BoolToOppositeBoolConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
if (targetType != typeof(bool)) {
throw new InvalidOperationException("The target must be a boolean");
}
if (null == value) {
return null;
}
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
if (targetType != typeof(bool)) {
throw new InvalidOperationException("The target must be a boolean");
}
if (null == value) {
return null;
}
return !(bool)value;
}
}
使用するには、resource-sectionで宣言します。
<local:BoolToOppositeBoolConverter x:Key="BoolToOppositeBoolConverter_ValueConverter"/>
そして、バインディングで静的リソースとして使用します。
<CheckBox IsChecked="{Binding YourProperty}" />
<CheckBox IsChecked="{Binding YourProperty,Converter={StaticResource BoolToOppositeBoolConverter_ValueConverter}}" />
コンバーターは単純な例にすぎないことに注意してください。本稼働コードで使用する場合は、きちんと実装してください。私はそれをテストしていません。機能しない場合はコメントしてください。
2つのラジオボタンのGroupNameプロパティを同じ値に設定すると、コンバーターなしでこれを実現できます(そのため、一度に1つしかチェックできません)。次に、1つのラジオボタンのIsCheckedを「True」に設定し、別のラジオボタンのIsCheckedをブール値にバインドします。ラジオボタンを切り替えるとブール値が変更されますが、ブール値をFalseに変更しても他のラジオボタンはチェックされません。
ありがとう、Vlad
サンプルコードを使用してラジオボタンを任意のタイプ(列挙、ブール、文字列、整数など)にバインドする方法のソリューションを次に示します。
http://www.codeproject.com/Tips/720497/Binding-Radio-Buttons-to-a-Single-Property
ragunathan の answer の簡易バージョン。
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
Convert(value);
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
Convert(value);
private object Convert(object value) =>
value is bool ? !(bool)value : value;