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

ove*_*mer 10 c# wpf radio-button

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

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

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

Pet*_*ore 11

试试这个:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这很棒。如果您使用此控件,请确保仅在其自己的 cs 文件中创建它,不要尝试使用其自己的 XAML 创建新的 UserControl。 (2认同)

Rac*_*hel 8

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

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

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

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

<Style x:Key="RadioButtonListBoxStyle" TargetType="{x:Type ListBox}">
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
                <Setter Property="Margin" Value="2, 2, 2, 0" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border Background="Transparent">
                                <RadioButton
                                    Content="{TemplateBinding ContentPresenter.Content}" VerticalAlignment="Center"
                                    IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

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

<ListBox ItemsSource="{Binding AvailableValues}"
         SelectedValue="{Binding SelectedValue}"
         Style="{StaticResource RadioButtonListBoxStyle}" />
Run Code Online (Sandbox Code Playgroud)

  • 感谢Bobby,当我看到所有次优答案时,我觉得我必须发布一些东西:)重要的是要记住在使用WPF时控件设计为无外观,这意味着你想选择一个支持的控件您想要的行为,即使默认情况下它看起来不像您想要的那样.你总是可以覆盖模板,使它看起来像你想要的:) (2认同)

dba*_*dba 6

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

<RadioButton Checked="RB_Checked" Click="RB_Clicked"/>
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

或者在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;
}
Run Code Online (Sandbox Code Playgroud)

单击Checked Event后的事件触发