[英]How to programmatically disable ComboBox items which satisfy condition
[英]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.