WPF + MVVM +单选按钮:如何处理与单个属性的绑定?

mnemlml8  于 2023-02-05  发布在  其他
关注(0)|答案(5)|浏览(218)

thisthis(和其他)问题堆栈溢出和许多其他材料在互联网上,我明白了如何绑定单选按钮(选项按钮)与视图模型。
但是他们都为单选按钮的每个可能的值创建了单独的属性。一个question与我的要求相似,但是被接受的答案建议使用ListBox而不是单选按钮。
例如,要表示人的性别(数据类型Char,可能值'M''F'),需要在视图模型中创建三个属性PersonGenderIsPersonMaleIsPersonFemale
我只想在一个属性PersonGender上控制它。我可以这样做吗?如果可以,怎么做?

de90aj5v

de90aj5v1#

你需要一个IValueConverter

//define this in the Window's Resources section or something similiarly suitable
<local:GenderConverter x:Key="genderConverterKey" />

<RadioButton Content="M" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=M}" />
<RadioButton Content="F" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=F}" />

该转换器

public class GenderConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((string)parameter == (string)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (bool)value ? parameter : null;        
    }
}

如果在这种情况下不应应用绑定,请将null(在ConvertBack中)替换为Binding.DoNothing

return (bool)value ? parameter : Binding.DoNothing;
xdnvmnnf

xdnvmnnf2#

使用命令(此处使用DelegateCommands
虚拟机:

public enum Genders {
    Female,
    Male
}
public YourVMClass {
    public Genders SelectedGender {get; set;}

    private DelegateCommand _cmdSelectGender;

    public DelegateCommand CmdSelectGender {
        get { return _cmdSelectGender ?? (_cmdSelectGender = new DelegateCommand(SelectGender)); }
    }

    private void SelectGender(Object parameter) {
        SelectedGender = (Genders)parameter;
    }
}

XAML:

<Window.Resources>
    <ObjectDataProvider x:Key="listOfGenders" MethodName="GetValues"
                        ObjectType="{x:Type System:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="loca:Genders"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Source={StaticResources listOfGenders}}">
    <ItemsControl.ItemTemplate>
        <RadioButton GroupName="Genders" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=DataContext.CmdSelectGender}" CommandParameter="{Binding}"/>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

(Didn(不测试代码,但这就是想法)

ma8fv8wu

ma8fv8wu3#

您的要求是可能的,但您需要做一些额外的工作才能使其工作。主要原因是RadioButton的属性IsCheckedBoolean,并且多个单选按钮是单独的控件,其作用与一个单选按钮不同。例如,ListBox。
为了满足您的要求,您可以使用转换器。将两个单选按钮的IsChecked绑定到ViewModel中的PersonGender属性,使用通用转换器并为雄性单选按钮传递参数“MALE”,为雌性单选按钮传递参数“FEMALE”。
在转换器中,检查参数PersonGender是否相同,并返回TRUE
即,如果复选框命令参数为MALE且PersonGender也为MALE,则启用复选框。否则,如果复选框命令参数为FEMALE且PersonGender为MALE,则不启用复选框,因为返回false。

yyyllmsg

yyyllmsg4#

我将solution转换器稍微更改为MarkupExtension,使其更易于使用(这里为int转换器):

public class RadioValueExtension : MarkupExtension, IValueConverter
{
    [ConstructorArgument("value")]
    public int Value { get; set; }

    public RadioValueExtension(int value)
    {
        Value = value;    
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Value == (int)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? Value : Binding.DoNothing;
    }
}

所以我可以这样使用它

<RadioButton IsChecked="{Binding Gender, Converter={converters:RadioValue 0}}" Content="M" />
<RadioButton IsChecked="{Binding Gender, Converter={converters:RadioValue 1}}" Content="F" />
nafvub8i

nafvub8i5#

你需要做的是使用IValueConverter,将Bool转换成Char,反之亦然。错误=〉“F”
在您的视图中有两个单选按钮。请确保在相同的组名中设置它们。然后,您需要将PersonGender仅绑定到IsMale单选按钮。因为此时IsFemale单选按钮处于选中状态。由于组名相同,IsMale单选按钮将自动处于未选中状态。

相关问题