【问题标题】:How to disable specific items of combobox programmatically by condition in wpf c#如何通过 wpf c# 中的条件以编程方式禁用组合框的特定项目
【发布时间】:2020-06-02 12:21:06
【问题描述】:

我想有条件地禁用某些特定的组合框项目。例如,我有两个组合框(combobox1,combobox2),我想根据combobox1的选定项禁用combobox2的某些特定项(不是删除,只是想禁用)。 我的 xaml 代码是这样的:

    <Grid>
    <ComboBox x:Name="combobox1" HorizontalAlignment="Left" Margin="142,99,0,0" VerticalAlignment="Top" Width="319">
        <ComboBoxItem>Choice1</ComboBoxItem>
        <ComboBoxItem>Choice2</ComboBoxItem>
        <ComboBoxItem>Choice3</ComboBoxItem>

    </ComboBox>
    <ComboBox x:Name="combobox2" HorizontalAlignment="Left" Margin="520,99,0,0" VerticalAlignment="Top" Width="358">
        <ComboBoxItem>Selection1</ComboBoxItem>
        <ComboBoxItem>Selection2</ComboBoxItem>
        <ComboBoxItem>Selection3</ComboBoxItem>
        <ComboBoxItem>Selection4</ComboBoxItem>
        <ComboBoxItem>Selection5</ComboBoxItem>
        <ComboBoxItem>Selection6</ComboBoxItem>
    </ComboBox>
</Grid>

C#代码是这样的:

    public partial class UC_Servis : UserControl
{
    public UC_Servis()
    {
        InitializeComponent();
    }
    private void combobox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        switch (combobox1.SelectedIndex)
        {
            case 0:
                combobox2.SelectedIndex = 0;
                break;
            case 1:
                combobox2.SelectedIndex = 1;
                break;
            case 2:
                combobox2.SelectedIndex = 2;
                break;
            default:
                break;
        }
        combobox2.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
    }
    private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
    {
        if (combobox2.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
        {
            foreach (var a in combobox2.Items)
            {
                int currentPosition = combobox2.Items.IndexOf(a);
                ComboBoxItem cbi = (ComboBoxItem)combobox2.ItemContainerGenerator.ContainerFromIndex(currentPosition);

                switch (combobox1.SelectedIndex)
                {
                    case 0:
                        switch (a.ToString())
                        {
                            case "Selection4":
                            case "Selection5":
                                cbi.IsEnabled = false;
                                break;
                            default:
                                cbi.IsEnabled = true;
                                break;
                        }
                        break;
                    case 1:
                        switch (a.ToString())
                        {
                            case "Selection1":
                            case "Selection3":
                                cbi.IsEnabled = false;
                                break;
                            default:
                                cbi.IsEnabled = true;
                                break;
                        }
                        break;
                    case 2:
                        switch (a.ToString())
                        {
                            case "Selection2":
                            case "Selection6":
                                cbi.IsEnabled = false;
                                break;
                            default:
                                cbi.IsEnabled = true;
                                break;
                        }
                        break;

                    default:
                        break;
                }
            }
        }
    }

}

当我运行时,没有任何变化,我无法禁用combobox2的任何项目。

我该怎么做?怎么了?

额外的问题

如果 Comboboxes 有静态项,我通过 neelesh bodgal 的支持来改变组合框项的显示能力。 但是,在我最初的研究中,组合框的项目源绑定到数据库,因此组合框的项目可以根据情况而变化。我尝试将 neelesh bodgal 的代码改编为我最初的研究,但所有项目都已启用。 在我原来的学习中,xaml 代码是这样的:

<Window x:Class="MyStudy.Pencereler.MamulStkConfig"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:MyStudy.Pencereler"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    mc:Ignorable="d"
    TextElement.Foreground="{DynamicResource MaterialDesignBody}"
    TextElement.FontWeight="Regular"
    TextElement.FontSize="13"
    TextOptions.TextFormattingMode="Ideal"
    TextOptions.TextRenderingMode="Auto"
    Background="{DynamicResource MaterialDesignPaper}"
    FontFamily="{DynamicResource MaterialDesignFont}"
    Title="MamulStkConfig" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" AllowsTransparency="True" WindowStyle="None" WindowState="Maximized" Width="1300" Height="700">
<Window.Resources>
    <local:TekerDisabler x:Key="tekerDisabler"/>
</Window.Resources>
<Grid>
                <ComboBox x:Name="Cbx_UrunGrubu" SelectionChanged="Cbx_UrunGrubu_SelectionChanged"  materialDesign:HintAssist.Hint="ÜRÜN GRUBU"  Style="{StaticResource MaterialDesignFloatingHintComboBox}" DisplayMemberPath="kodTipTanim" SelectedValuePath="kodTipId" />
                <ComboBox x:Name="Cbx_Secim1" SelectionChanged="Cbx_Secim1_SelectionChanged"  materialDesign:HintAssist.Hint="{Binding ElementName=txt_Hint1,Path=Text}"  Style="{StaticResource MaterialDesignFloatingHintComboBox}" DisplayMemberPath="TANIM" SelectedValuePath="KOD" />
                <ComboBox x:Name="Cbx_Secim2" SelectionChanged="Cbx_Secim2_SelectionChanged"  materialDesign:HintAssist.Hint="{Binding ElementName=txt_Hint2,Path=Text}"  Style="{StaticResource MaterialDesignFloatingHintComboBox}" DisplayMemberPath="TANIM" SelectedValuePath="KOD" />
                <ComboBox x:Name="Cbx_Secim3" SelectionChanged="Cbx_Secim3_SelectionChanged"  materialDesign:HintAssist.Hint="{Binding ElementName=txt_Hint3,Path=Text}"  Style="{StaticResource MaterialDesignFloatingHintComboBox}" DisplayMemberPath="TANIM" SelectedValuePath="KOD" />
                <ComboBox x:Name="Cbx_Ops10" SelectionChanged="Cbx_Ops10_SelectionChanged"  materialDesign:HintAssist.Hint="{Binding ElementName=txt_Hint10,Path=Text}"  Style="{StaticResource MaterialDesignFloatingHintComboBox}" DisplayMemberPath="TANIM" SelectedValuePath="KOD"  >
                <ComboBox.ItemContainerStyle>
                   <Style TargetType="ComboBoxItem">
                      <Setter Property="IsEnabled">
                         <Setter.Value>
                            <MultiBinding Converter="{StaticResource tekerDisabler}">
                              <Binding ElementName="Cbx_UrunGrubu" Path="SelectedItem"/>
                              <Binding ElementName="Cbx_Ops3" Path="SelectedItem"/>
                              <Binding ElementName="Cbx_Ops2" Path="SelectedItem"/>
                              <Binding RelativeSource="{RelativeSource Self}"/>
                            </MultiBinding>
                         </Setter.Value>
                      </Setter>
                   </Style>
                </ComboBox.ItemContainerStyle>
            </ComboBox>
</Grid>

MyStudy C# 代码是这样的:

    public class TekerDisabler : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        bool enable = true;
        var cbxUrunGrupSelectedItem = values[0] as ComboBoxItem;
        var cbxOp3SelectedItem = values[1] as ComboBoxItem;
        var cbxOp2SelectedItem = values[2] as ComboBoxItem;
        var cbxOp10Item = values[3] as ComboBoxItem;
        if (cbxUrunGrupSelectedItem == null || cbxOp2SelectedItem == null || cbxOp3SelectedItem == null || cbxOp10Item == null)
            return true;
        switch (cbxUrunGrupSelectedItem.Content.ToString())
        {
            case "DÖNERLİ PULLUK":
                switch (cbxOp3SelectedItem.Content.ToString())
                {
                    case "(100X100X10) Profil":
                        if (cbxOp10Item.Content.ToString() == "LASTİK TEKER BÜYÜK (10x80-12)") { enable = false; }
                        break;
                    case "(120X120X10) Profil":
                        switch (cbxOp2SelectedItem.Content.ToString())
                        {
                            case "3'LÜ (2+1)":
                            case "3'LÜ (3+0)":
                            case "3'LÜ (FLANŞSIZ)":
                                if (cbxOp10Item.Content.ToString() == "TEKERSİZ" || cbxOp10Item.Content.ToString() == "LASTİK TEKER BÜYÜK (10x80-12)")
                                { enable = false; }
                                break;
                            case "1'Lİ (1+0)":
                            case "1'Lİ (FLANŞSIZ)":
                            case "2'Lİ (1+1)":
                            case "2'Lİ (2+0)":
                            case "2'Lİ (FLANŞSIZ)":
                                if (cbxOp10Item.Content.ToString() == "LASTİK TEKER BÜYÜK (10x80-12)")
                                { enable = false; }
                                break;
                            default:
                                if (cbxOp10Item.Content.ToString() == "TEKERSİZ" || cbxOp10Item.Content.ToString() == "DEMİR TEKER" || cbxOp10Item.Content.ToString() == "LASTİK TEKER (20,5x8,00-10)")
                                { enable = false; }
                                break;
                        }
                        break;
                    case "(140X140X10) Profil":
                    case "(140X140X14) Profil":
                        if (cbxOp10Item.Content.ToString() == "TEKERSİZ" || cbxOp10Item.Content.ToString() == "DEMİR TEKER" || cbxOp10Item.Content.ToString() == "LASTİK TEKER (20,5x8,00-10)")
                        { enable = false; }
                        break;

                    default:
                        enable = true;
                        break;
                }
                break;
            default:
                break;
        }
        return enable;
    }

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

我该如何克服这个问题?

【问题讨论】:

    标签: c# wpf combobox


    【解决方案1】:

    这是使用数据绑定的另一种方式。 这是工作代码。您可以在项目中替换此代码并检查。

      <UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <local:Disabler x:Key="disabler"/>
    </UserControl.Resources>
    <Grid>
    <ComboBox x:Name="combobox1" HorizontalAlignment="Left" Margin="142,99,0,0" 
            VerticalAlignment="Top" Width="319">
            <ComboBoxItem>Choice1</ComboBoxItem>
            <ComboBoxItem>Choice2</ComboBoxItem>
            <ComboBoxItem>Choice3</ComboBoxItem>
    
        </ComboBox>
    
         <ComboBox x:Name="combobox2" HorizontalAlignment="Left" Margin="520,99,0,0" VerticalAlignment="Top" Width="358">
            <ComboBoxItem>Selection1</ComboBoxItem>
            <ComboBoxItem>Selection2</ComboBoxItem>
            <ComboBoxItem>Selection3</ComboBoxItem>
            <ComboBoxItem>Selection4</ComboBoxItem>
            <ComboBoxItem>Selection5</ComboBoxItem>
            <ComboBoxItem>Selection6</ComboBoxItem>
    
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="IsEnabled">
                        <Setter.Value>
                            <MultiBinding Converter="{StaticResource disabler}">
                                <!--Here you can bind the proper u want to use in -->
                                <!--converter to enable/ disable comboboxitem-->
                                <Binding ElementName="combobox1" Path="SelectedItem"/>
    
                                <!--Bind to the current comboboxitem which needs to enabled/disabled-->
                                <Binding RelativeSource="{RelativeSource Self}"/>
                            </MultiBinding>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
    </UserControl>
    

    在后面的代码中定义转换器如下

        using System;
        using System.Globalization;
        using System.Windows.Controls;
        using System.Windows.Data;
    
        namespace WpfApplication1
        {
            /// <summary>
            /// Interaction logic for UserControl1.xaml
            /// </summary>
            public partial class UserControl1 : UserControl
            {
                public UserControl1()
                {
                    InitializeComponent();
                }
            }
    
            class Disabler : IMultiValueConverter
            {
                public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
                {
    
                    bool enable = true;
                    var comboxbox1SelectedItem = values[0] as ComboBoxItem;
                    var comboxbox2Item = values[1]  as ComboBoxItem;
    
                    if (comboxbox1SelectedItem == null || comboxbox2Item == null)
                        return true;
    
                    if (comboxbox1SelectedItem.Content.ToString() == "Choice1")
                    {
                        if(comboxbox2Item.Content.ToString() == "Selection4" || (comboxbox2Item.Content.ToString() == "Selection5")){
                            enable = false;
                        }
                    }
                    else if (comboxbox1SelectedItem.Content.ToString() == "Choice2")
                    {
                        if (comboxbox2Item.Content.ToString() == "Selection1" || (comboxbox2Item.Content.ToString() == "Selection3")){
                            enable = false;
                        }
                    }
                    else if (comboxbox1SelectedItem.Content.ToString() == "Choice3")
                    {
                        if (comboxbox2Item.Content.ToString() == "Selection2" || (comboxbox2Item.Content.ToString() == "Selection6")){
                            enable = false;
                        }
                    }
                    return enable;
                }
    
                public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
                {
                    throw new NotImplementedException();
                }
            }
        }
    

    对于多个决定启用/禁用项目的组合框,可以将相同的示例扩展如下

        <UserControl x:Class="WpfApplication1.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApplication1"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
           <local:Disabler x:Key="disabler"/>
           <local:Disabler2 x:Key="disabler2"/>
        </UserControl.Resources>
       <Grid>
       <ComboBox x:Name="combobox1" HorizontalAlignment="Left" Margin="142,99,0,0" 
        VerticalAlignment="Top" Width="319">
        <ComboBoxItem>Choice1</ComboBoxItem>
        <ComboBoxItem>Choice2</ComboBoxItem>
        <ComboBoxItem>Choice3</ComboBoxItem>
    
       </ComboBox>
    
       <ComboBox x:Name="combobox2" HorizontalAlignment="Left" Margin="142,99,0,0" 
        VerticalAlignment="Top" Width="319">
        <ComboBoxItem>Choice21</ComboBoxItem>
        <ComboBoxItem>Choice22</ComboBoxItem>
        <ComboBoxItem>Choice23</ComboBoxItem>
    
       </ComboBox>
    
     <ComboBox x:Name="combobox3" HorizontalAlignment="Left" Margin="520,99,0,0" VerticalAlignment="Top" Width="358">
        <ComboBoxItem>Selection1</ComboBoxItem>
        <ComboBoxItem>Selection2</ComboBoxItem>
        <ComboBoxItem>Selection3</ComboBoxItem>
        <ComboBoxItem>Selection4</ComboBoxItem>
        <ComboBoxItem>Selection5</ComboBoxItem>
        <ComboBoxItem>Selection6</ComboBoxItem>
    
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter Property="IsEnabled">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource disabler2}">
                            <!--Here you can bind the proper u want to use in -->
                            <!--converter to enable/ disable comboboxitem-->
                            <Binding ElementName="combobox1" Path="SelectedItem"/>
                            <Binding ElementName="combobox2" Path="SelectedItem"/>
                            <!--Bind to the current comboboxitem which needs to enabled/disabled-->
                            <Binding RelativeSource="{RelativeSource Self}"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style>
        </ComboBox.ItemContainerStyle>
        </ComboBox>
        </Grid>
        </UserControl>
    

    您可以创建一个新的 valueconveter 来处理三个项目,如下所示

        class Disabler2 : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
    
                bool enable = true;
                var comboxbox1SelectedItem = values[0] as ComboBoxItem;
                var comboxbox2SelectedItem = values[1]  as ComboBoxItem;
                var comboxbox3Item = values[2]  as ComboBoxItem;
    
                //Logic to disable items
    
                return enable;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    【讨论】:

    • 非常感谢您提供这种有趣的解决方案。
    • 您可以通过Data binding 了解更多信息。很高兴它对您有所帮助。
    • Thnx neelesh bodgal 。例如,如果我对另一个组合框项目的禁用有多个组合框标准,我该怎么做?
    • 看看答案,我已经更新了代码。可以将相同的概念扩展到可以决定启用和禁用的任意数量的组合框。
    • 谢谢你,neelesh bodgal。这就是我需要的。只是,我们需要像这样修复 Disabler2 中的 1 行: var comboxbox2SelectedItem = values[1] as ComboBoxItem;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多