繁体   English   中英

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

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

我想有条件地禁用 combobox 的某些特定项目。 例如,我有两个组合框(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 的任何项目。

我怎样才能做到这一点? 怎么了?

额外的问题

如果组合框有 static 项目,我通过 neelesh bodgal 的支持完成了更改 combobox 项目的显示能力。 但是,在我最初的研究中,组合框的项目源绑定到数据库,因此组合框的项目可以根据情况而变化。 我尝试使 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();
    }
}

我怎样才能克服这个问题?

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

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

对于不止一个 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>

您可以创建一个新的 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