简体   繁体   English

如何通过 wpf c# 中的条件以编程方式禁用 combobox 的特定项目

[英]How to disable specific items of combobox programmatically by condition in wpf c#

I want to disable some specific items of combobox conditionally.我想有条件地禁用 combobox 的某些特定项目。 For Example, I have two comboboxes (combobox1,combobox2), I want to disable some specific items of combobox2 (not to remove, just want to disable) according to selected item of combobox1.例如,我有两个组合框(combobox1,combobox2),我想根据combobox1的选定项禁用combobox2的某些特定项(不是删除,只是想禁用)。 My xaml codes are like that:我的 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>

and C# codes are like that:和 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;
                }
            }
        }
    }

}

When I run, there is no change, I could not make none of the items of combobox2 disabled.当我运行时,没有任何变化,我无法禁用 combobox2 的任何项目。

How can I do that?我怎样才能做到这一点? what's wrong?怎么了?

EXTRA QUESTION额外的问题

If Comboboxes have static items, I accomplished to change displaying ability of combobox items by support of neelesh bodgal.如果组合框有 static 项目,我通过 neelesh bodgal 的支持完成了更改 combobox 项目的显示能力。 But, in my original study, comboboxes' item sources are binded to database, so items of comboboxes' items can change by situations.但是,在我最初的研究中,组合框的项目源绑定到数据库,因此组合框的项目可以根据情况而变化。 I tryed to adapt neelesh bodgal's codes to my original study, but all of the items are enabled.我尝试使 neelesh bodgal 的代码适应我最初的研究,但所有项目都已启用。 in my original study xaml codes are like that:在我原来的研究中 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>

And MyStudy C# codes are like that: 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();
    }
}

How can I overcome this problem?我怎样才能克服这个问题?

This is a another way of doing it using data binding.这是使用数据绑定的另一种方法。 This is working code.这是工作代码。 You can replace this code in your project and check.您可以在项目中替换此代码并检查。

  <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>

Define the converter in the code behind as follows在后面的代码中定义转换器如下

    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();
            }
        }
    }

For more than one combobox deciding the enable/disable items, same example can be extended as follows对于不止一个 combobox 决定启用/禁用项目,同样的例子可以扩展如下

    <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>

You can create a new valueconveter for processing three item as follows您可以创建一个新的 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();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM