互斥复选框-C#,MVVM

互斥复选框-C#,MVVM,c#,wpf,mvvm,checkbox,C#,Wpf,Mvvm,Checkbox,我正在写一个有两种可能的程序:手动设置时间和日期,或使用计算机/系统时间和日期 现在我需要做两个相互排斥的复选框。当选择一个时,必须取消选中另一个。如何在MVVM中实现这一点 <CheckBox Name="UseSystemTime" Margin="7" Content="Use System Time and Date settings (Time, Date, DST, Timezone)" IsChecked="{Binding UseSystemTime}"/> <

我正在写一个有两种可能的程序:手动设置时间和日期,或使用计算机/系统时间和日期

现在我需要做两个相互排斥的复选框。当选择一个时,必须取消选中另一个。如何在MVVM中实现这一点

<CheckBox Name="UseSystemTime" Margin="7"  Content="Use System Time and Date settings (Time, Date, DST, Timezone)" IsChecked="{Binding UseSystemTime}"/>
<CheckBox Name="ManualTime" Margin="7"  Content="Set settings Manually" IsChecked="{Binding SetSettingsManually}"/>

在XAML中有这样做的方法吗


谢谢

您可以从IValueConverter接口实现BoottoCheckBoxConverter,并传递ConvertorParameter以取消选中复选框


在您只有2个
复选框的情况下
我只会在我的viewmodel中为ManualTime类引入一个bool属性

public bool IsManualTimeUsed
{
   // get;set with property-changed 
}
在UI中,您有两个机会:

机会1:

 <CheckBox Name="UseSystemTime" Margin="7" Content="Use System Time and Date settings (Time, Date, DST, Timezone)" 
           IsChecked="{Binding IsManualTimeUsed, Converter{converterNamespace:InverseBoolConverter}}"/>
 <CheckBox Name="ManualTime" Margin="7" Content="Set settings Manually" 
           IsChecked="{Binding IsManualTimeUsed}"/>
机会2

<CheckBox Name="UseSystemTime" Margin="7" Content="Use System Time and Date settings (Time, Date, DST, Timezone)" 
          IsChecked="{Binding ElementName=ManualTime, Path=IsChecked, Converter={converterNamespace:InverseBoolConverter}}"/>
<CheckBox Name="ManualTime" Margin="7" Content="Set settings Manually" 
          IsChecked="{Binding IsManualTimeUsed}"/>

使用与机会1中相同的转换器

但是checkbox的形式更漂亮(更用户友好)-我想是这样:)我更愿意使用checkbox,或者可以将radiobutton的形状更改为checkbox形式:)使用复选标记和everythink?:)

您可以为
单选按钮
创建一个样式,使其看起来像一个
复选框

    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
    <Style x:Key="OptionMarkFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/>
    <SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/>
    <SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/>
    <SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/>
    <SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/>
    <SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/>
    <SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/>
    <SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/>
    <SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/>
    <SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
    <Style x:Key="CheckBoxRadioButtonStyle" TargetType="{x:Type RadioButton}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Border x:Name="checkBoxBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                            <Grid x:Name="markGrid">
                                <Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph}" Margin="1" Opacity="0" Stretch="None"/>
                                <Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph}" Margin="2" Opacity="0"/>
                            </Grid>
                        </Border>
                        <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasContent" Value="true">
                            <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
                            <Setter Property="Padding" Value="4,-1,0,0"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Background}"/>
                            <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Border}"/>
                            <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
                            <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Background}"/>
                            <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Border}"/>
                            <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
                            <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Background}"/>
                            <Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Border}"/>
                            <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
                            <Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="true">
                            <Setter Property="Opacity" TargetName="optionMark" Value="1"/>
                            <Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="{x:Null}">
                            <Setter Property="Opacity" TargetName="optionMark" Value="0"/>
                            <Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

然后像这样使用它:

<RadioButton Style="{StaticResource CheckBoxRadioButtonStyle}" />

(我刚刚使用了默认的
复选框
样式并更改了目标类型)


但是,我强烈建议您使用普通的单选按钮,因为用户对它很熟悉。互斥复选框可能会让用户感到奇怪。

如果需要任何问题,请询问为什么不使用单选按钮?它们是显示互斥选项的传统方式,可能更容易设置。感谢您的想法。对此也有思考。但是checkbox的形式更漂亮(更用户友好)-我想是这样:)我更愿意使用checkbox,或者可以将radiobutton的形状更改为checkbox形式:)使用复选标记和everythink?:)你应该总是问你的用户他们喜欢什么,在制作任何软件时不要把你的意见视为最好的。当您需要互斥行为时,使用单选按钮(具有默认外观)是标准行为。将默认外观更改为其他标准控件可能会让用户感到困惑。事实上,你可以做一些事情并不意味着你应该总是这样做。在所有这些评论之后,如果你仍然想使用你以前使用的方法,那么你需要为你的IsChecked属性使用转换器。可能是MulnButdIn尝试“机会2”的转换器,并且我得到错误:“在Windows演示基础(WPF)项目中不支持反相BooLover。”为什么我会这样?我实现了-XAML代码和C#in-view模型。我建议将转换器放在一个名为Converter的单独文件夹中。而在XAML的窗口声明中,您必须将其包含在
xmlns:converter=PATHTOCONVERTER
中,才能使用它
<RadioButton Style="{StaticResource CheckBoxRadioButtonStyle}" />