CheckBox DataTriggers

时间:2017-08-31 15:30:15

标签: wpf

我有以下两个带有datatriggers的复选框。如果我单击combo1,它将按预期取消选中combo2,但在再次单击之前,combo1将不会被检查。反过来也是这样。这是为什么?

<CheckBox Name="cbx1" VerticalAlignment="Center" Content="1">
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbx2}" Value="True">
                    <Setter Property="IsChecked" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

<CheckBox Name="cbx2" VerticalAlignment="Center" Content="2">
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbx1}" Value="True">
                    <Setter Property="IsChecked" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

2 个答案:

答案 0 :(得分:2)

您可以为这两种样式添加一个setter,以确保始终检查至少一个CheckBox是否符合您的要求:

<CheckBox Name="cbx1" VerticalAlignment="Center" Content="1">
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Setter Property="IsChecked" Value="True"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbx2}" Value="True">
                    <Setter Property="IsChecked" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

<CheckBox Name="cbx2" VerticalAlignment="Center" Content="2">
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Setter Property="IsChecked" Value="True"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbx1}" Value="True">
                    <Setter Property="IsChecked" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

答案 1 :(得分:2)

如果您的要求是允许用户取消选中这两个框,则无法使用触发器以声明方式执行此操作,因为(反对我先前在评论中的疯狂讨价还价),当触发器&# 39; s条件停止为真,它试图撤消它以前做过的事情。

以下是我对你所看到的内容的猜测:

  1. 用户检查A.
  2. B触发器通过将B放入&#34;未选中&#34;来响应当前当前状态。州。
  3. 用户检查B.
  4. A触发器通过将A放入&#34;未选中&#34;来响应当前当前状态。州。
  5. B触发器将A状态更改为&#34;未选中&#34;,并将B返回其默认状态 - 未选中。
  6. 现在两者都未经检查,用户可以随意检查其中任何一个并且它会保持这种状态。
  7. 如果您将mm8建议的默认状态更改为True,那么就无法取消选中。如果您使用默认状态False,则很难检查任何

    但这有效:

    <CheckBox 
        Name="cbx1" 
        Content="1"
        Tag="{Binding ElementName=cbx2}"
        Checked="twinnedCheckBox_Checked"
        />
    <CheckBox 
        Name="cbx2" 
        Content="2"
        Tag="{Binding ElementName=cbx1}"
        Checked="twinnedCheckBox_Checked"
        />
    

    代码背后:

    private void twinnedCheckBox_Checked(object sender, RoutedEventArgs e)
    {
        var self = sender as CheckBox;
        var twin = self.Tag as CheckBox;
    
        if ((bool)twin.IsChecked)
            twin.IsChecked = false;
    }
    

    您可以通过简单地编写附加的行为属性来在XAML中设置此twin behavior

    更新:您可以使用DataTrigger.EnterActions和Storyboards:

    在纯XAML中执行此操作
    <CheckBox Name="cb3" VerticalAlignment="Center" Content="3">
        <CheckBox.Style>
            <Style TargetType="CheckBox">
                <Setter Property="IsChecked" Value="False"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked, ElementName=cb4}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames
                                        Storyboard.TargetProperty="IsChecked"
                                        >
                                        <DiscreteBooleanKeyFrame KeyTime="0" Value="False" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </CheckBox.Style>
    </CheckBox>
    
    <CheckBox Name="cb4" VerticalAlignment="Center" Content="4">
        <CheckBox.Style>
            <Style TargetType="CheckBox">
                <Setter Property="IsChecked" Value="False"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked, ElementName=cb3}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames
                                        Storyboard.TargetProperty="IsChecked"
                                        >
                                        <DiscreteBooleanKeyFrame KeyTime="0" Value="False" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </CheckBox.Style>
    </CheckBox>