什么是一组3个单选按钮绑定到值1,2,或3 int类型的属性的最简单的方法?简单的WPF RadioButton绑定?
回答
其实,利用转换器一样,打破两正如我上面所说的,你也不能在枚举中使用它。更好的方式来做到这一点是针对一个ListBox简单的款式,就像这样:
注:相反的是DrWPF.com在他们的例子说明,做不把ContentPresenter的单选按钮内,否则如果添加一个包含按钮或其他内容的项目,您将无法设置焦点或与其进行交互。这项技术解决了这个问题。此外,您需要处理文本的灰色以及删除标签上的边距,否则将无法正确呈现。这种风格也适合你。
<Style x:Key="RadioButtonListItem" TargetType="{x:Type ListBoxItem}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<DockPanel LastChildFill="True" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Center" >
<RadioButton IsChecked="{TemplateBinding IsSelected}" Focusable="False" IsHitTestVisible="False" VerticalAlignment="Center" Margin="0,0,4,0" />
<ContentPresenter
Content = "{TemplateBinding ContentControl.Content}"
ContentTemplate = "{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat = "{TemplateBinding ContentControl.ContentStringFormat}"
HorizontalAlignment = "{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment = "{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels = "{TemplateBinding UIElement.SnapsToDevicePixels}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RadioButtonList" TargetType="ListBox">
<Style.Resources>
<Style TargetType="Label">
<Setter Property="Padding" Value="0" />
</Style>
</Style.Resources>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="ItemContainerStyle" Value="{StaticResource RadioButtonListItem}" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="HorizontalRadioButtonList" BasedOn="{StaticResource RadioButtonList}" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Background="Transparent" Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
你现在有单选按钮的外观和感觉,但你可以做双向绑定,你可以使用一个枚举。以下是如何...
<ListBox Style="{StaticResource RadioButtonList}"
SelectedValue="{Binding SomeVal}"
SelectedValuePath="Tag">
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Yet another option</ListBoxItem>
</ListBox>
而且,因为我们明确地分离出来是tragets的ListBoxItem中,而不是把它内嵌的风格,再次作为其他例子已经表明,你现在可以创建一个新的风格断它根据每个项目(如间距)定制事物。 (如果你只是尝试目标ListBoxItem的配合键样式将覆盖通用的控制目标,这是行不通的。)
这里的推杆6保证金每个项目的上面和下面的一个例子。 (请注意,您如何有通过ItemContainerStyle属性明确应用的样式,而不是简单地为理由ListBox的资源区段定位ListBoxItem的上述说明。)
<Window.Resources>
<Style x:Key="SpacedRadioButtonListItem" TargetType="ListBoxItem" BasedOn="{StaticResource RadioButtonListItem}">
<Setter Property="Margin" Value="0,6" />
</Style>
</Window.Resources>
<ListBox Style="{StaticResource RadioButtonList}"
ItemContainerStyle="{StaticResource SpacedRadioButtonListItem}"
SelectedValue="{Binding SomeVal}"
SelectedValuePath="Tag">
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Ter another option</ListBoxItem>
</ListBox>
希望这会有所帮助,当然,如果你喜欢这个,请标记为已接受或投票给我! :)
+1,但如果这是'将3个单选按钮绑定到值为1,2或3的int类型属性的最简单方法,那么它对WPF来说并不是很好。它真的超越了我,为什么他们使事情变得简单,让事情变得如此头痛难以且不必要的复杂 – 2012-04-30 13:36:44
这实际上不仅仅是因为它设计了一个列表框,而是一个单一的控件,所以绑定的工作原理如此简单(一旦你获得通过疯狂的设置。)但是,我同意RadioButton类肯定有一些绑定的缺点。当然,你可以用代码隐藏的方式做得更简单,但是在这里这种方式,你只需要做一次样式等,然后稍后使用它就容易多了。 – MarqueIV 2012-04-30 15:43:54
OMG,简单吗?尽管对你的回答和努力给予了应有的尊重,但称这种“简单的风格”却相当牵强,不是吗? WPF和Winforms的核心思想和感知优势不是更好的数据绑定?在WPF投放市场多年之后,一个简单的单选按钮(和单选按钮分组)如何破坏绑定是我无法理解的。对MS感到羞耻。 – 2015-03-18 10:49:23
我想出了一个简单的解决方案。
我有一个model.cs类:
private int _isSuccess;
public int IsSuccess { get { return _isSuccess; } set { _isSuccess = value; } }
我Window1.xaml.cs用的DataContext设置为model.cs文件。 XAML中包含了单选按钮:
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=1}" Content="one" />
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=2}" Content="two" />
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=3}" Content="three" />
这里是我的转换器:
public class RadioBoolToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int integer = (int)value;
if (integer==int.Parse(parameter.ToString()))
return true;
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return parameter;
}
}
当然,在窗口1的资源:
<Window.Resources>
<local:RadioBoolToIntConverter x:Key="radioBoolToIntConverter" />
</Window.Resources>
这个转换器的问题是它不适用于枚举作为参数(你的ToString()调用死亡。)看到我的答案在下面。 – MarqueIV 2010-11-07 21:43:38
你只需要改变你的转换器来解析枚举 – 2012-04-12 21:05:52
再一次,这不适用于双向绑定。 'Convert Back'调用会尝试让多个事物设置不同的绑定值,在这种情况下,当您尝试将属性IsSuccess设置为一个值时遇到竞争条件,而另一个尝试将其设置为不同的值。这是这种方法的问题。当然,这是更少的代码,但你仍然有单独的控件都试图改变一个属性。 (记住,当你选择一个单选按钮时,它会取消选择另一个单选按钮,因此会有两个更改。) – MarqueIV 2012-07-14 00:38:20
我知道它的方式方法姗姗来迟,但我有一个替代的解决方案,这是更轻,更简单。从System.Windows.Controls.RadioButton
派生类并声明两个依赖项属性RadioValue
和RadioBinding
。然后在类代码,重写OnChecked
并设置RadioBinding
属性值的RadioValue
属性值。在另一方向,陷阱使用回调改变为RadioBinding
属性,并且如果新的值等于RadioValue
属性的值,其IsChecked
属性设置为true
。
下面的代码:
public class MyRadioButton : RadioButton
{
public object RadioValue
{
get { return (object)GetValue(RadioValueProperty); }
set { SetValue(RadioValueProperty, value); }
}
// Using a DependencyProperty as the backing store for RadioValue.
This enables animation, styling, binding, etc...
public static readonly DependencyProperty RadioValueProperty =
DependencyProperty.Register(
"RadioValue",
typeof(object),
typeof(MyRadioButton),
new UIPropertyMetadata(null));
public object RadioBinding
{
get { return (object)GetValue(RadioBindingProperty); }
set { SetValue(RadioBindingProperty, value); }
}
// Using a DependencyProperty as the backing store for RadioBinding.
This enables animation, styling, binding, etc...
public static readonly DependencyProperty RadioBindingProperty =
DependencyProperty.Register(
"RadioBinding",
typeof(object),
typeof(MyRadioButton),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnRadioBindingChanged));
private static void OnRadioBindingChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
MyRadioButton rb = (MyRadioButton)d;
if (rb.RadioValue.Equals(e.NewValue))
rb.SetCurrentValue(RadioButton.IsCheckedProperty, true);
}
protected override void OnChecked(RoutedEventArgs e)
{
base.OnChecked(e);
SetCurrentValue(RadioBindingProperty, RadioValue);
}
}
XAML用法:
<my:MyRadioButton GroupName="grp1" Content="Value 1"
RadioValue="val1" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 2"
RadioValue="val2" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 3"
RadioValue="val3" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 4"
RadioValue="val4" RadioBinding="{Binding SelectedValue}"/>
希望有人认为这有用的这段时间:)
我很惊讶,没有人想出了这个类。的解决方案将其绑定到bool阵列上。它可能不是最干净的,但它可以很轻松的使用:
private bool[] _modeArray = new bool[] { true, false, false};
public bool[] ModeArray
{
get { return _modeArray ; }
}
public int SelectedMode
{
get { return Array.IndexOf(_modeArray, true); }
}
在XAML:
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[0], Mode=TwoWay}"/>
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[1], Mode=TwoWay}"/>
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[2], Mode=TwoWay}"/>
注意:你不需要双向绑定,如果你不想给一个默认选中。双向绑定是这种解决方案的最大缺点。
优点:
- 无需代码背后
- 无需额外的类(IValue转换器)
- 无需额外枚举
- 犯规需要的bizzare结合
- 简单,易于了解
- 不违反MVVM(嘿,至少我希望如此)
我也很惊讶。此解决方案适用于那些WPF新手,只知道如何进行绑定并希望快速绑定单选按钮。这非常简单直接。 +1 – QuantumHive 2014-08-26 11:53:56
这是很好的,在写出我自己的'Converter'之前,很快就会投入测试。 +1 – 2015-01-07 19:59:16
只是一个小建议:从C#6开始,你不再需要支持领域了。只需使用AutoProperty:public bool [] ModeArray {get; } = new bool [] {true,false,false}; – oopbase 2016-05-12 08:08:42
这个例子看起来有点冗长,但其意图应该很清楚。
它在ViewModel中使用3个布尔属性,FlagForValue1
,FlagForValue2
和FlagForValue3
。 这三个属性中的每一个都由称为_intValue
的单个私人字段支持。
view(xaml)的3个单选按钮每个绑定到视图模型中相应的Flag属性。这意味着显示“值1”的单选按钮绑定到视图模型中的FlagForValue1
布尔属性,其他两个相应地绑定。
当设置在视图模型的属性之一(例如FlagForValue1
),它重要也提高属性改变为其他两个属性事件(例如FlagForValue2
,和FlagForValue3
),所以在UI(WPF INotifyPropertyChanged
基础设施)可以选择/正确取消每个单选按钮。
private int _intValue;
public bool FlagForValue1
{
get
{
return (_intValue == 1) ? true : false;
}
set
{
_intValue = 1;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
public bool FlagForValue2
{
get
{
return (_intValue == 2) ? true : false;
}
set
{
_intValue = 2;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
public bool FlagForValue3
{
get
{
return (_intValue == 3) ? true : false;
}
set
{
_intValue = 3;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
的XAML看起来是这样的:
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue1, Mode=TwoWay}"
>Value 1</RadioButton>
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue2, Mode=TwoWay}"
>Value 2</RadioButton>
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue3, Mode=TwoWay}"
>Value 3</RadioButton>
请添加一些解释 – 2015-07-23 07:45:01
丑陋像罪,但基本上我也是这么做的。 – 2016-10-02 05:49:34
有时可以解决它在这样的模式: 假设你有3个布尔属性OptionA,OptionB,OptionC中。
XAML:
<RadioButton IsChecked="{Binding OptionA}"/>
<RadioButton IsChecked="{Binding OptionB}"/>
<RadioButton IsChecked="{Binding OptionC}"/>
CODE:
private bool _optionA;
public bool OptionA
{
get { return _optionA; }
set
{
_optionA = value;
if(_optionA)
{
this.OptionB= false;
this.OptionC = false;
}
}
}
private bool _optionB;
public bool OptionB
{
get { return _optionB; }
set
{
_optionB = value;
if(_optionB)
{
this.OptionA= false;
this.OptionC = false;
}
}
}
private bool _optionC;
public bool OptionC
{
get { return _optionC; }
set
{
_optionC = value;
if(_optionC)
{
this.OptionA= false;
this.OptionB = false;
}
}
}
你的想法。 不是最干净的事情,但容易。
我想出了解决方案,使用Binding.DoNothing
从转换器返回不会破坏双向绑定。
public class EnumToCheckedConverter : IValueConverter
{
public Type Type { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value.GetType() == Type)
{
try
{
var parameterFlag = Enum.Parse(Type, parameter as string);
if (Equals(parameterFlag, value))
{
return true;
}
}
catch (ArgumentNullException)
{
return false;
}
catch (ArgumentException)
{
throw new NotSupportedException();
}
return false;
}
else if (value == null)
{
return false;
}
throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value is bool check)
{
if (check)
{
try
{
return Enum.Parse(Type, parameter as string);
}
catch(ArgumentNullException)
{
return Binding.DoNothing;
}
catch(ArgumentException)
{
return Binding.DoNothing;
}
}
return Binding.DoNothing;
}
throw new NotSupportedException();
}
}
用法:
<converters:EnumToCheckedConverter x:Key="SourceConverter" Type="{x:Type monitor:VariableValueSource}" />
单选按钮绑定:
<RadioButton GroupName="ValueSource"
IsChecked="{Binding Source, Converter={StaticResource SourceConverter}, ConverterParameter=Function}">Function</RadioButton>
- 1. Radiobutton wpf绑定
- 2. Wpf RadioButton组绑定
- 3. WPF简单绑定
- 4. 简单的WPF + MVVM绑定
- 5. WPF简单数据绑定
- 6. WPF简单绑定问题
- 7. ItemsControl中的WPF RadioButton IsChecked绑定路径
- 8. WPF DataGrid绑定Radiobutton列属性
- 9. 简单的WPF MVVM绑定问题
- 10. 简单的WPF绑定无法工作
- 11. 将WPF单选按钮绑定到ViewModel中的RadioButton`
- 12. WPF简单绑定到对象属性
- 13. WPF简单绑定在代码后面
- 14. WPF简单绑定到INotifyPropertyChanged对象
- 15. 简写和单手WPF绑定等效
- 16. XAML双向绑定RadioButton IsChecked
- 17. WPF中的单向绑定的简单问题
- 18. 绑定问题与RadioButton
- 19. 简单的绑定不工作在jQuery中的Radiobutton的IE浏览器
- 20. Javascript简单绑定
- 21. 通过绑定设置WPF DependencyProperty的RadioButton控件集合
- 22. 简单的WinJS ListView绑定
- 23. 简单的角度绑定
- 24. 简单的Emacs键绑定
- 25. 简单绑定的问题
- 26. 简单的绑定问题
- 27. 有没有简单的方法绑定到WPF中的父行?
- 28. 简单的地方捕捉更改绑定的XML在WPF
- 29. 简单地绑定到WPF应用程序中的类
- 30. 从ObservableCollection到DataGrid(WPF)的简单数据绑定?
看一看这个博客条目:> [WPF单选按钮和数据绑定(http://geekswithblogs.net /claraoscura/archive/2008/10/17/125901.aspx) – Nifle 2009-08-23 07:40:26
请看解决方案[在WPF中的RadioButton的Binding IsChecked属性](http://pstaev.blogspot.com/2008/10/binding-ischecked-property -of.html),它就像一个魅力。原来的问题已被修复为WPF 4.0! – 2009-11-06 15:43:14
一个更好,更通用的解决方案可以在这个答案中找到:http://stackoverflow.com/a/406798/414306 – 2012-12-28 12:54:34