问题描述
我正在尝试将自定义类绑定到WPF应用程序中的一组3个单选按钮。根据选择组中的哪个按钮,应该有三种返回类的可能性。因此,即
public class RadioButtonResult
{
public bool Istrue {get; set;}
public string WhichOne {get; set;}
}
应按按钮1返回的方式绑定到3个单选按钮
new RadioButtonResult { Istrue = false,WhichOne = "First"}
第二个实例返回一个Istrue = true的实例,等等...我需要这样做,因为存在3种可能的情况,并且该元素必须同时绑定到布尔属性和字符串属性。
我尝试使用转换器
public class RadioButtonConverter : IValueConverter
{
public object Convert(object value,Type targettype,object parameter,CultureInfo culture)
{
switch (parameter)
{
case "First":
return new RadioButtonResult(false,"First");
case "Second":
return new RadioButtonResult(true,"Second");
case "Third":
return new RadioButtonResult(true,"First");
default:
return new RadioButtonResult(false,"None")
}
}
public object ConvertBack(object value,CultureInfo culture)
{ return null; }
}
单选按钮本身应该没有文本,因此我不太确定如何传递转换器参数甚至尝试这样做。 (我尚未尝试使用ConvertBack,因为无法使Convert正常工作)
<RadioButton GroupName="Group1" IsChecked="{Binding TestStatus,Converter=RadioButtonConverter,ConverterParameter="First"}"/>
我尝试了类似的方法,但是它不接受文本作为参数。我该如何使此转换器工作?
解决方法
我不知道如何将字符串和bool绑定到一组3个单选按钮上
您可以在视图模型中拥有6个属性或重用RadioButtonClass
类(如果要动态更改值,请考虑实现INotifyPropertyChanged
)
public class ViewModel
{
public RadioButtonResult Button1 { get; } = new RadioButtonResult(false,"First");
... // more buttons
}
<RadioButton GroupName="Group1"
IsChecked="{Binding Button1.Istrue}"
Content="{Binding Button1.WhichOne}" />
public MainWindow()
{
InitializeComponents();
DataContext = new ViewModel();
}
,
我认为您的viewmodel结构应该更像:
public class RadioButtonResult
{
public bool Istrue {get; set;}
public string WhichOne {get; set;}
public List<OptionVM> Options {get; set;}
}
OptionVM将具有两个属性:
public bool Istrue {get; set;}
public string Descriptor {get; set;}
IsTrue的设置者应该启动一些逻辑。
因此:
private bool isTrue = false;
public bool Istrue
{ get => isTrue;
set { isTrue = value;
SetTheParentValue();
}
}
SetTheParentValue应该是一个注入到视图模型的Action。这将引用RadioButtonResult,并在其中将true设置为true或false并设置WhereOne。因此,您还需要一个公共Action SetTheParentValue。
您应该实现inotifypropertychanged。
没有转换器。
您的逻辑会付诸行动,以便这些类可用于其他单选按钮组。
我们对您的总体结构了解不足,无法就其他方面提供建议。
但是。
单选按钮集是一个重复组,在wpf中通过将itemscontrol的itemssource绑定到视图模型的列表或可观察的集合进行处理。这就是OptionVM。然后将数据模板化为单选按钮。
单选按钮的ischecked属性将绑定到IsTrue,内容绑定到Descriptor。
,我建议不要为每个单选按钮组使用一个单独的枚举值。
要进行绑定,您将需要在枚举值和单选按钮的布尔值IsChecked属性之间转换。
public class perValueEqualsConverter : IValueConverter
{
public object Convert(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture)
{
return parameter != null && parameter.Equals(value);
}
public object ConvertBack(object value,System.Globalization.CultureInfo culture)
{
return value != null && value.Equals(true) ? parameter : Binding.DoNothing;
}
}
enum属性是在ViewModel中定义的...
public enum MyEnum
{
Value1,Value2,Value3
}
public class MainViewModel : ViewModelBase
{
private MyEnum _e = MyEnum.Value2;
public MyEnum E
{
get => _e;
set => Set(nameof(E),ref _e,value);
}
}
...,然后通过转换器实例用作View中的绑定源
<Window
...>
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Window.Resources>
<conv:perValueEqualsConverter x:Key="ValueEqualsConverter" />
</Window.Resources>
<Grid Margin="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="16" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Width=200>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="8" />
<RowDefinition Height="Auto" />
<RowDefinition Height="8" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton
Grid.Row="0"
Content="Value 1"
IsChecked="{Binding E,Converter={StaticResource ValueEqualsConverter},ConverterParameter={x:Static local:MyEnum.Value1}}" />
<RadioButton
Grid.Row="2"
Content="Value 2"
IsChecked="{Binding E,ConverterParameter={x:Static local:MyEnum.Value2}}" />
<RadioButton
Grid.Row="4"
Content="Value 3"
IsChecked="{Binding E,ConverterParameter={x:Static local:MyEnum.Value3}}" />
</Grid>
<Border
Grid.Row="0"
Margin="-8"
BorderBrush="Black"
BorderThickness="2"
CornerRadius="8" />
<TextBlock
Grid.Row="2"
Text="{Binding E}" />
</Grid>
</Window>