在XAML中使用RadioButtons启用/禁用WPF控件

时间:2014-04-02 12:44:35

标签: c# wpf xaml radio-button

我的问题是我有一组RadioButtons,我想根据选择的RadioButton禁用另一个控件。

如果选择了几个 RadioButton,我可以禁用控件。

E.g。

[] Enabled one
[] Enabled two
[] Disabled one
[] Disabled two

如果选择了最后两个按钮之一,则应禁用该控件。

注意

我打算自己回答这个问题(Which should be ok according to this link)但如果他们以更好的方式解决问题,我会接受其他答案。

2 个答案:

答案 0 :(得分:5)

如果这是您需要它的唯一地方,那么可以使用您的简单解决方案,但我认为在实际应用中您可能会多次遇到这种情况,所以我更喜欢使用一般解决方案来制作事情比较简单。 对我来说,我将使用MultiConverter使用逻辑OR从其他几个布尔值计算结果布尔值,如下所示:

<Window.Resources>
    <converters:MultiBoolOrConverter x:Key="MultiBoolOrConverter" />
</Window.Resources>
<StackPanel>
    <RadioButton GroupName="group" x:Name="enabledOne">Enabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="enabledTwo">Enabled two</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledOne">Disabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledTwo">Disabled two</RadioButton>

<TextBox Text="Test">   
    <TextBox.IsEnabled>
        <MultiBinding Converter="{StaticResource MultiBoolOrConverter}">
            <Binding Path="IsChecked" ElementName="enabledOne" />
            <Binding Path="IsChecked" ElementName="enabledTwo" />
        </MultiBinding>
    </TextBox.IsEnabled>
</TextBox>

</StackPanel>

和使用过的MultiBoolOrConverter.cs转换器类:

using System;
using System.Linq;
using System.Globalization;
using System.Windows.Data;

namespace StackOverFlowTest.Converters
{
    class MultiBoolOrConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values.Cast<bool>().Any(value => value);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

您还可能遇到需要使用AND而不是OR的情况,这里是MultiBoolAndConverter转换器:

using System;
using System.Linq;
using System.Globalization;
using System.Windows.Data;

namespace StackOverFlowTest.Converters
{
    class MultiBoolAndConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values.Cast<bool>().All(value => value);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

我希望这会对你有帮助。

更新---------------------

在我以前的解决方案中,我使用了逻辑:

The control should be enabled if one of the first two buttons are selected.

而不是字面上的问题:

The control should be disabled if one of the last two buttons are selected.

它当然是有效的,但是如果你想要它完全如你所描述的那样代码将需要很少的改变来使用转换器来否定IsChecked布尔值:

<Window.Resources>
<converters:MultiBoolAndConverter x:Key="MultiBoolAndConverter" />
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
</Window.Resources>
<StackPanel>
    <RadioButton GroupName="group" x:Name="enabledOne">Enabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="enabledTwo">Enabled two</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledOne">Disabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledTwo">Disabled two</RadioButton>

<TextBox Text="Test">   
    <TextBox.IsEnabled>
        <MultiBinding Converter="{StaticResource MultiBoolAndConverter}">
            <Binding Path="IsChecked" ElementName="disabledOne" Converter="{StaticResource BoolNegationConverter}" />
            <Binding Path="IsChecked" ElementName="disabledTwo" Converter="{StaticResource BoolNegationConverter}" />
        </MultiBinding>
    </TextBox.IsEnabled>
</TextBox>

</StackPanel>

BoolNegationConverter.cs

using System;
using System.Globalization;
using System.Windows.Data;

namespace StackOverFlowTest.Converters
{
    class BoolNegationConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(value is bool && (bool)value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(value is bool && (bool)value);
        }
    }
}

答案 1 :(得分:2)

我想出的解决方案是:

<Window.Resources>
    <Style TargetType="TextBox" x:Key="enableDisableStyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsChecked, ElementName=disabledOne}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding IsChecked, ElementName=disabledTwo}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<StackPanel>
    <RadioButton GroupName="group" x:Name="enabledOne">Enabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="enabledTwo">Enabled two</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledOne">Disabled one</RadioButton>
    <RadioButton GroupName="group" x:Name="disabledTwo">Disabled two</RadioButton>

    <TextBox Text="Test" Style="{StaticResource enableDisableStyle}" />
</StackPanel>

在我确信这是最佳解决方案之前,我不会将自己的答案标记为已接受。