如何取消选中WPF(MVVM)中的单选按钮

我有一个单选按钮组。 填写表格不是强制性的选择。 开始时,所有单选按钮都未选中。 如果用户无意中点击其中一个,他就无法返回,因为至少需要检查一个。

那么如何取消选中一个单选按钮而不强迫用户做出不必要的选择呢?

ps表单是在运行时构建的,我遵循MVVM设计模式。 对于强制性选择,单选按钮解决方案非常适合我在这种情况下已经使用它。

就个人而言,当我想要这种行为时,我使用ListBox并覆盖模板以使用RadioButtons

它是适合执行以下所有操作的最佳控件:

  • 显示项目列表
  • 一次只能选择一个项目,因此在数据模型中只保留一个属性
  • 用户可以将所选项目保留为空,表示未选择任何项目

我对ListBox自定义样式删除了边框和背景颜色,并使用RadioButton绘制每个项目,并将IsChecked绑定到ListBoxItem.IsSelected。 通常是这样的:

     

而显示RadioButtons本身通常非常简单,如下所示:

  

我在这个场景中使用了一些Eventhandler

  

在XAML的Codebehind中:

 Private JustChecked as Boolean Private Sub RB_Checked(sender As Object, e As RoutedEventArgs) Dim s As RadioButton = sender ' Action on Check... JustChecked = True End Sub Private Sub RB_Clicked(sender As Object, e As RoutedEventArgs) If JustChecked Then JustChecked = False e.Handled = True Return End If Dim s As RadioButton = sender If s.IsChecked Then s.IsChecked = False End Sub 

或者在C#中

 private bool JustChecked; private void RB_Checked(object sender, RoutedEventArgs e) { RadioButton s = sender; // Action on Check... JustChecked = true; } private void RB_Clicked(object sender, RoutedEventArgs e) { if (JustChecked) { JustChecked = false; e.Handled = true; return; } RadioButton s = sender; if (s.IsChecked) s.IsChecked = false; } 

单击Checked Event后的事件触发

试试这个:

 public class OptionalRadioButton : RadioButton { #region bool IsOptional dependency property public static DependencyProperty IsOptionalProperty = DependencyProperty.Register( "IsOptional", typeof(bool), typeof(OptionalRadioButton), new PropertyMetadata((bool)true, (obj, args) => { ((OptionalRadioButton)obj).OnIsOptionalChanged(args); })); public bool IsOptional { get { return (bool)GetValue(IsOptionalProperty); } set { SetValue(IsOptionalProperty, value); } } private void OnIsOptionalChanged(DependencyPropertyChangedEventArgs args) { // TODO: Add event handler if needed } #endregion protected override void OnClick() { bool? wasChecked = this.IsChecked; base.OnClick(); if ( this.IsOptional && wasChecked == true ) this.IsChecked = false; } } 

你的单选按钮:

 Some Radio Button 

代码背后:

  MyRadioButton.IsChecked = false; 

如果要使用绑定取消选中它,请执行以下操作:

代码背后:

 public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); this.DataContext = this; } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); } #endregion private bool _isRadioChecked; public bool IsRadioChecked { get { return _isRadioChecked; } set { _isRadioChecked = value; OnPropertyChanged("IsRadioChecked"); } } } 

xaml(查看):

 Some Radio Button 

正如@Tomtom指出的那样,你可以使用Checkboxes,但这也可以同时检查多个选项, 或者你必须实现一个复杂的机制来确保只检查一个选项。时间。

另一个非常便宜的解决方法是在您的单选按钮选项中添加一个额外的条目。

您是怎么知道我们的 ?

  • 谷歌
  • 一个朋友
  • 电视上的广告
  • 其他

我同意Tomtom的说法, RadioButton可能不是最好的设计选择,但是如果这个选择不在您的控制之内或者由于其他原因而需要,那么您将需要一些强制取消选择的机制。

以下是一些可能性:

  • RadioButton组附近的清除按钮
  • 取消选中已经检查过的RadioButton ,如果再次单击它。
  • 右键单击选中的RadioButton时,提供上下文菜单“清除”选项

由于表单是在运行时构建的,因此在创建控件时需要附加相应的事件处理程序,如下所示:

  // Create an instance of the control var controlType = typeof(Control).Assembly.GetType(fullyQualifiedControl, true); var control = Activator.CreateInstance(controlType); switch (fullyQualifiedControl) { case "System.Windows.Controls.RadioButton": ((RadioButton)control).Checked += new RoutedEventHandler(DataDrivenControl_Checked); ((RadioButton)control).Unchecked += new RoutedEventHandler(DataDrivenControl_UnChecked); break; } 

脏的方法是创建折叠的RadioButton

      

如果用户点击已经选中的RadioButton,请检查空的RadioButton

代码背后

 private void RadioButton_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) { var radioButton = sender as RadioButton; if (radioButton.IsChecked.GetValueOrDefault()) { rbEmpty.IsChecked = true; e.Handled = true; } } 

我知道这一天的答案有点晚了但是我在使用UWP时遇到了类似的问题,我认为这可能会有所帮助。 我正在开发一个自定义菜单,用户可以在其中选择和取消选项,我的解决方案显示在以下测试代码中:

主页Xaml:

          

主页代码背后:

 public sealed partial class MainPage : Page { private bool rb1PrevState; private bool rb2PrevState; private bool rb3PrevState; private bool rb4PrevState; private bool rb5PrevState; public MainPage() { this.InitializeComponent(); rb1PrevState = this.RB1.IsChecked.Value; rb2PrevState = this.RB2.IsChecked.Value; rb3PrevState = this.RB3.IsChecked.Value; rb4PrevState = this.RB4.IsChecked.Value; rb5PrevState = this.RB5.IsChecked.Value; } private void RBtn_Click(object sender, RoutedEventArgs e) { RadioButton rbtn = sender as RadioButton; if (rbtn != null) { if (rbtn.IsChecked.Value == true) { switch (rbtn.Name) { case "RB1": if (rb1PrevState == true) { rbtn.IsChecked = false; rb1PrevState = false; } else { rb1PrevState = true; ResetRBPrevStates("RB1"); } break; case "RB2": if (rb2PrevState == true) { rbtn.IsChecked = false; rb2PrevState = false; } else { rb2PrevState = true; ResetRBPrevStates("RB2"); } break; case "RB3": if (rb3PrevState == true) { rbtn.IsChecked = false; rb3PrevState = false; } else { rb3PrevState = true; ResetRBPrevStates("RB3"); } break; case "RB4": if (rb4PrevState == true) { rbtn.IsChecked = false; rb4PrevState = false; } else { rb4PrevState = true; ResetRBPrevStates("RB4"); } break; case "RB5": if (rb5PrevState == true) { rbtn.IsChecked = false; rb5PrevState = false; } else { rb5PrevState = true; ResetRBPrevStates("RB5"); } break; default: break; } } } } private void ResetRBPrevStates(string _excludeRB) { rb1PrevState = (_excludeRB == "RB1" ? rb1PrevState : false); rb2PrevState = (_excludeRB == "RB2" ? rb2PrevState : false); rb3PrevState = (_excludeRB == "RB3" ? rb3PrevState : false); rb4PrevState = (_excludeRB == "RB4" ? rb4PrevState : false); rb5PrevState = (_excludeRB == "RB5" ? rb5PrevState : false); } } 

这对我来说效果很好,就我而言,并没有违反任何MVVM规则。

嗨,这是如何每次点击它来检查和取消选中单选按钮。

  int click = 0; private void RadioButton_Click(object sender, RoutedEventArgs e) { click++; ((RadioButton)sender).IsChecked = click % 2 == 1 ; click %= 2; } 

在这种情况下,您不应使用RadioButton 。 此控件的目的是始终检查一个。 在您的场景中,我更喜欢使用CheckBox

无法取消选中RadioButton 。 如果你必须继续使用RadioButton ,我会添加一个默认的“未选择”选项。 在这种情况下,我更喜欢带有空项目的ComboBox或顶部的清除按钮。