WPF绑定声明性语法:未设置复选框时启用GroupBox

时间:2011-07-07 15:36:33

标签: wpf syntax binding declarative

我是WPF的新手,如果这是一个愚蠢的问题,请提前原谅我。如果选中了复选框,我有启用GroupBox的语法,这很好用:

IsEnabled="{Binding ElementName=cbIsDeceased, Path=IsChecked}"

但我需要的是翻转极性。当未选中复选框时,我需要IsEnabled为true,反之亦然。是否有声明的方法来获得它?

感谢。

2 个答案:

答案 0 :(得分:2)

您必须添加转换器以反转布尔值。 在XAML中,定义转换器的资源并将其添加到绑定:

IsEnabled="{Binding ElementName=cbIsDeceased, Path=IsChecked, Converter={StaticResource InverseBooleanConverter}"

为了省时间,我给你的转换器版本,非常简单:)

/// <summary>
/// Converts a boolean to its opposite value
/// </summary>
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter: IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (targetType != typeof(bool))
            throw new InvalidOperationException("The target must be a boolean");

        return !(bool)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion
}

答案 1 :(得分:0)

要在XAML中完全实现此目的(即,没有转换器),您可以使用由CheckBox的Checked和Unchecked事件触发的基于keframe的动画。请注意,这不是Binding,并且没有任何东西“监视”CheckBox的状态以确定是否应该启用GroupBox。这就是为什么(正如您将在下面的示例中看到的)必须明确设置GroupBox和CheckBox的初始状态才能使动画正常工作。

这是一个有效的例子:

<Window ...>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <GroupBox
            x:Name="targetGroupBox"
            Grid.Row="0"
            Header="My GroupBox"
            IsEnabled="False"
            >
            <Button Content="Hello World" />
        </GroupBox>

        <CheckBox
            Grid.Row="1"
            Content="Toggle with animation"
            IsChecked="True"
            >
            <CheckBox.Triggers>
                <EventTrigger RoutedEvent="CheckBox.Checked">
                    <EventTrigger.Actions>
                        <StopStoryboard BeginStoryboardName="SetFalseStoryboard" />
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="CheckBox.Unchecked">
                    <EventTrigger.Actions>
                        <BeginStoryboard Name="SetFalseStoryboard">
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames
                                    Storyboard.TargetName="targetGroupBox"
                                    Storyboard.TargetProperty="IsEnabled"
                                    AutoReverse="True"
                                    BeginTime="0:0:0"
                                    FillBehavior="HoldEnd"
                                    >
                                    <DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0" />
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </CheckBox.Triggers>
        </CheckBox>
    </Grid>
</Window>

显示此视图时,仅当取消选中“动画”CheckBox时,才会启用父GroupBox中的Button。因为这不是绑定,所以可能存在性能问题,即重复执行的绑定转换器可能比重复“播放”的基于关键帧的动画执行得更好;我还没有进行任何性能测试来验证。

我过去曾经谨慎地使用过这样的动画,因为我讨厌编写和引用转换器的功能,我觉得应该将其内置到WPF开箱即用中。但是,大多数情况下,转换器是最佳选择,此示例仅表示在某些情况下,基于关键帧的动画可用于完全在XAML中实现所需的结果。