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

时间:2017-08-28 12:02:31

标签: c# wpf combobox visibility

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

这是我的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 particullar, 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 particullar, 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"/>    

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

运行时,我得到nullreferenceExecption或InvalidCastException。 (参见Code中的注释.comboBoxFilter2_Selectionchange方法中的相同错误。

1 个答案:

答案 0 :(得分:2)

使用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));
        }
    }
}

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

用法:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel() { Selected1 = "a", Selected2 = "d" };
    }
}