C# 使用3个组合框selecteditem值控制按钮启用状态

C# 使用3个组合框selecteditem值控制按钮启用状态,c#,wpf,xaml,C#,Wpf,Xaml,我正在开发一个WPF应用程序。我有3个组合框。每个组合框都有一个列表作为源,每个组合框中有3项:1、2、3。 我也有一个按钮。如果用户在至少2个组合框中选择了相同的值,我想禁用该按钮。 即,如果用户在第一个CB中选择1,在第二个CB中也选择1,则禁用该按钮。我已经试着用下面的代码来实现这个按钮。 但它无论如何都不起作用 <Button> .... <Style> <Style.Triggers> <MultiDataTrigge

我正在开发一个WPF应用程序。我有3个组合框。每个组合框都有一个列表作为源,每个组合框中有3项:1、2、3。 我也有一个按钮。如果用户在至少2个组合框中选择了相同的值,我想禁用该按钮。 即,如果用户在第一个CB中选择1,在第二个CB中也选择1,则禁用该按钮。我已经试着用下面的代码来实现这个按钮。 但它无论如何都不起作用

<Button>
....
<Style> 
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding ElementName=CB1, Path=SelectedItem}" Value="1" />
                <Condition Binding="{Binding ElementName=CB2, Path=SelectedItem}" Value="1" />
                <Condition Binding="{Binding ElementName=CB3, Path=SelectedItem}" Value="1" />
            </MultiDataTrigger.Conditions>
            <Setter Property="IsEnabled" Value="False" />
        </MultiDataTrigger>
    </Style.Triggers>
</Style>
</Button>

....

您能推荐一个更好的解决方案,在
XAML
本身中也能做到这一点吗?

我将使用
多值转换器来实现这一点:

public class IsDistinctConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Distinct().Count() == values.Length;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
如果传递列表中的所有项都是唯一的,则
Convert
方法返回
true
。在XAML中,您可以使用如下转换器:

<Button Content="My Button">
    <Button.Resources>
        <!-- You can move this Resource to another place without any problem -->
        <local:IsDistinctConverter x:Key="IsDistinctConverter"/>
    </Button.Resources>
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource IsDistinctConverter}">
            <Binding Path="SelectedItem" ElementName="CB1"/>
            <Binding Path="SelectedItem" ElementName="CB2"/>
            <Binding Path="SelectedItem" ElementName="CB3"/>
        </MultiBinding>
    </Button.IsEnabled>
</Button>

我将使用
多值转换器来实现这一点:

public class IsDistinctConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Distinct().Count() == values.Length;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
如果传递列表中的所有项都是唯一的,则
Convert
方法返回
true
。在XAML中,您可以使用如下转换器:

<Button Content="My Button">
    <Button.Resources>
        <!-- You can move this Resource to another place without any problem -->
        <local:IsDistinctConverter x:Key="IsDistinctConverter"/>
    </Button.Resources>
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource IsDistinctConverter}">
            <Binding Path="SelectedItem" ElementName="CB1"/>
            <Binding Path="SelectedItem" ElementName="CB2"/>
            <Binding Path="SelectedItem" ElementName="CB3"/>
        </MultiBinding>
    </Button.IsEnabled>
</Button>


您正在使用MVVM吗?如果是这样,那么您可以使用RelayCommand绑定到按钮的命令。然后命令将能够根据您的ViewModel状态决定按钮是否应该处于活动状态。我已经在使用
RelayCommand
来控制这样的按钮状态。我正在寻找一些在XAML中控制它的技术。你在使用MVVM吗?如果是这样,那么您可以使用RelayCommand绑定到按钮的命令。然后命令将能够根据您的ViewModel状态决定按钮是否应该处于活动状态。我已经在使用
RelayCommand
来控制这样的按钮状态。我正在寻找一些技术来控制XAML本身。是否有可能将其包含在自身中?@Rennie您可以尝试将
多重绑定
设置为
Setter
中的值。这应该行得通。但是您仍然需要对
组合框的引用。这就是为什么我看不出为什么需要将绑定移动到样式。是否有可能将其包含在自身中?@Rennie您可以尝试将
多重绑定
设置为
Setter
中的值。这应该行得通。但是您仍然需要对
组合框的引用。这就是为什么我看不出为什么需要将绑定移动到样式。