根据第二个组合框的选择隐藏组合框项目,反之亦然

Posted

技术标签:

【中文标题】根据第二个组合框的选择隐藏组合框项目,反之亦然【英文标题】:Hiding combobox items based on choice of second combobox, vice versa 【发布时间】:2018-02-05 16:41:56 【问题描述】:

我有两个组合框,每个都绑定(!)到相同的ObservableCollection<string>。我想阻止选择相同的项目。

这是我的C#代码(firstload bool只是为了防止函数第一次加载时执行):

private void comboBoxFilter1_SelectionChanged(object sender, SelectionChangedEventArgs e)

    if (!firstload)
    
        for (int i = 0; i <= comboBoxFilter2.Items.Count - 1; i++)
        
            if ((((ComboBoxItem)(comboBoxFilter2.Items[i])).Content as string) == (((ComboBoxItem)comboBoxFilter1.SelectedItem).Content as string))
            // This is where I get the InvalidCaseException ^
            
                (comboBoxFilter2.Items[i] as ComboBoxItem).Visibility = System.Windows.Visibility.Collapsed;
                //and on this line the nullreferenceException, in particular, although the Item[i] does have Value!
            
            else
            
                (comboBoxFilter2.Items[i] as ComboBoxItem).Visibility = System.Windows.Visibility.Visible;
                //and on this line the nullreferenceException, in particular, although the Item[i] does have Value!
            
        
    


private void comboBoxFilter2_SelectionChanged(object sender, SelectionChangedEventArgs e)
            
    if (!firstload)
    
        for (int i = 0; i <= comboBoxFilter1.Items.Count - 1; i++)
        
            if ((((ComboBoxItem)(comboBoxFilter1.Items[i])).Content as string) == (((ComboBoxItem)comboBoxFilter2.SelectedItem).Content as string))
            
                (comboBoxFilter1.Items[i] as ComboBoxItem).Visibility = System.Windows.Visibility.Collapsed;
            
            else
            
                MessageBox.Show((comboBoxFilter2.Items[i] as ComboBoxItem).Visibility.ToString());
                (comboBoxFilter1.Items[i] as ComboBoxItem).Visibility = System.Windows.Visibility.Visible;
            
        
    

    firstload = false;

这是我的 Xaml:

<ComboBox x:Name="comboBoxFilter1" 
          Grid.Column="0" 
          Grid.Row="2"     
          HorizontalAlignment="Stretch" 
          VerticalAlignment="Bottom"     
          SelectionChanged="comboBoxFilter1_SelectionChanged" 
          SelectedIndex="0"     
          Visibility="Visible"/>    

<ComboBox x:Name="comboBoxFilter2" 
          Grid.Column="1" Grid.Row="2"     
          HorizontalAlignment="Stretch" 
          VerticalAlignment="Bottom"     
          SelectionChanged="comboBoxFilter2_SelectionChanged" 
          SelectedIndex="1"    
          Visibility="Visible"/>    

请注意,我在代码中而不是在 Xaml 中执行 Itemsource。

运行时,我得到一个NullReferenceExecptionInvalidCastException(参见代码中的 cmets)。 comboBoxFilter2_SelectionChange 方法中也会出现同样的错误。

【问题讨论】:

请原谅我可怕的后期制作,我真的不明白格式是如何工作的...... 当安全转换 (Combobox.Items[i] as ComboboxItem) 不成功时,可能会发生 Nullreference 异常。您应该调试并查看值的确切类型。 我建议使用IMultiValueConverter 并使用转换器将第一个ComboBoxVisibility 绑定到第一个和第二个ComboBoxSelectedItem,反之亦然。更简洁,更容易理解,并且没有代码。 购买方式:你真的想在选择相同的项目时折叠ComboBox / span> id 喜欢让第一个 Combobox 显示 [a,b,c,e],其中选择了 a,第二个 Combobox 显示 [b,c,d,e],其中选择了 d跨度> 【参考方案1】:

使用 MVVM 完成此类任务非常简单,您很少需要使用视图事件/元素来实现所需。

如果你有这样的 xaml:

<StackPanel>
    <ComboBox ItemsSource="Binding List1" SelectedItem="Binding Selected1" />
    <ComboBox ItemsSource="Binding List2" SelectedItem="Binding Selected2" />
</StackPanel>

然后所有的逻辑都可以进入viewmodel:

public class ViewModel : INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string property = "") => 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));

    readonly List<string> _list = new List<string>  "a", "b", "c", "d", "e" ;
    public IEnumerable<string> List1 => _list.Where(o => o != Selected2);
    public IEnumerable<string> List2 => _list.Where(o => o != Selected1);

    string _selected1;
    public string Selected1
    
        get  return _selected1; 
        set
        
            _selected1 = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(List2));
        
    

    string _selected2;
    public string Selected2
    
        get  return _selected2; 
        set
        
            _selected2 = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(List1));
        
    

注意:当视图更改所选项目时,视图模型会简单地为绑定中使用的属性触发NotifyPropertyChanged 事件并评估它们的值。

用法:

public partial class MainWindow : Window

    public MainWindow()
    
        InitializeComponent();
        DataContext = new ViewModel()  Selected1 = "a", Selected2 = "d" ;
    

【讨论】:

以上是关于根据第二个组合框的选择隐藏组合框项目,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

如何使用组合框根据另一个组合框的值从不同的表中选择数据

基于两个组合框选择的过滤器表单

使用组合框过滤记录并填充第二个组合框

在数据表或连续表单视图中的表单上,我们如何将第二个组合框中的可能值基于第一个组合框中选择的值?

如何在 WPF 中隐藏组合框的项目

尝试根据另一个组合框的选择填充两个组合框