I am trying to debug a strange error in combobox related to itemssource and selecteditem. It drives me crazy.
The problem occurs when changing the selected tabitem in which the combined function exists. (In fact, this is only when changing the DataContext for the ComboBox). Binding SelectedItem has a custom validationrule function to throw an error if the value is null.
The problem is that wpf calls my custom rule when switching tabitems (DataContext) and tries to check for null, even if the selected source is never zero. This is problem.
This is a simplified case that I made that shows the same error:
Set a breakpoint in NotNullValidationRule.Validate and see how WPF tries to validate the SelectedItem value as null, even if it is not present in any instance of the view model.
UPDATE
After several experiments, I found that TabControl does not actually matter. Even with a simple ComboBox and a button to switch the DataContext, I get the exact same problem. I am replacing the sample code with the new version.
using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace ComboBoxValidationBugTest { public partial class MainWindow : Window { private Test t1, t2; public MainWindow() { InitializeComponent(); t1 = new Test(); t1.Items.Add("A"); t1.Items.Add("B"); t1.Items.Add("C"); t1.SelectedItem = "A"; t2 = new Test(); t2.Items.Add("B"); t2.Items.Add("C"); t2.Items.Add("D"); t2.SelectedItem = "B"; ComboBox1.DataContext = t1; } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { ComboBox1.DataContext = ComboBox1.DataContext == t1 ? t2 : t1; } } public class Test : INotifyPropertyChanged { private string _selectedItem; private ObservableCollection<string> _items = new ObservableCollection<string>(); public ObservableCollection<string> Items { get { return _items; } } public string SelectedItem { get { return _selectedItem; } set { _selectedItem = value; OnPropertyChanged("SelectedItem"); } } public override string ToString() { return _selectedItem; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } public class NotNullValidationRule : ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { if (value == null) { return new ValidationResult(false, "Value was null"); } return new ValidationResult(true, null); } } }
And XAML:
<Window x:Class="ComboBoxValidationBugTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:comboBoxValidationBugTest="clr-namespace:ComboBoxValidationBugTest" Title="MainWindow" Height="350" Width="525"> <Grid> <DockPanel> <Button Content="Toggle DataContext" DockPanel.Dock="Top" Click="ButtonBase_OnClick" /> <ComboBox ItemsSource="{Binding Items}" VerticalAlignment="Top" x:Name="ComboBox1"> <ComboBox.SelectedItem> <Binding Path="SelectedItem"> <Binding.ValidationRules> <comboBoxValidationBugTest:NotNullValidationRule /> </Binding.ValidationRules> </Binding> </ComboBox.SelectedItem> </ComboBox> </DockPanel> </Grid> </Window>
source share