我有两个组合框,每个组合框都绑定(!)到同一个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方法中的相同错误。
答案 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" };
}
}