WPF ComboBox文本搜索使用切换按钮的IsChecked属性导致NullReferenceException

时间:2016-12-07 10:37:13

标签: c# wpf xaml data-binding combobox

我遇到了WPF组合框的问题,并在用户按下数据中未出现的字符后更改了数据源。

<Label Name="FavoriteFoodLbl" Grid.Column="0" Grid.Row="13">Favorite Food</Label>
<ComboBox Name="FavoriteFoodCombo" Grid.Column="1" Grid.Row="13" ItemsSource="{Binding Foods}" SelectedItem="{Binding FavoriteFood, UpdateSourceTrigger=PropertyChanged}" />

<Label Name="FavoriteFlavourLbl" Grid.Column="2" Grid.Row="13">Favorite Flavour</Label>
<ComboBox Name="FavoriteFlavourCombo" Grid.Column="3" Grid.Row="13" ItemsSource="{Binding Flavours}"  />

代码....

    public ObservableCollection<string> Foods { get; set; } = new ObservableCollection<string>() { "Pizza", "Ice Cream", "Soup" };

    private string _favoriteFood;
    public string FavoriteFood
    {
        get { return _favoriteFood; }
        set
        {
            _favoriteFood = value;
            switch (_favoriteFood)
            {
                case "Pizza":
                    _flavours = new ObservableCollection<string>(PizzaToppings);
                    break;
                case "Ice Cream":
                    _flavours = new ObservableCollection<string>(IceCreamFlavours);
                    break;
                case "Soup":
                    _flavours = new ObservableCollection<string>(SoupFlavours);
                    break;
                default:
                    _flavours = new ObservableCollection<string>(new List<string>() { "None" });
                    break;
            }
            this.FavoriteFlavour = null;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FavoriteFood"));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Flavours"));
        }
    }

    public List<string> PizzaToppings { get; set; } = new List<string>() { "Margarita", "Pepperoni", "Meat Feast" };
    public List<string> IceCreamFlavours { get; set; } = new List<string>() { "Vanilla", "Strawberry", "Chocolate" };
    public List<string> SoupFlavours { get; set; } = new List<string>() { "Tomato", "Leek and Potato", "Chicken" };

    private ObservableCollection<string> _flavours = null;
    public ObservableCollection<string> Flavours
    {
        get
        {
            return _flavours;
        }
        set
        {
            _flavours = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Flavours"));
        }
    }

    string _favoriteFlavour;
    public string FavoriteFlavour
    {
        get
        {
            return _favoriteFlavour;
        }

        set
        {
            _favoriteFlavour = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FavoriteFlavour"));
        }
    }

仅当用户通过键入(而不是通过鼠标单击)选择第二个组合框中的值时,才会出现此问题。 重现的步骤:

  1. 选择喜欢的食物,例如比萨饼
  2. 使用Tab键移至第二个组合
  3. 按下已知选项的第一个字母,例如按'P'代表“Pepperoni”
  4. 按另一个没有选项的字母,即按“e”,就像你还在输入“Pepperoni”一样
  5. 现在选择不同喜欢的食物,例如冰淇淋。值“Pepperoni”应该从第二个框中消失。
  6. 现在用鼠标,尝试选择最喜欢的冰淇淋口味。
  7. 此时我被抛出异常......

    Activated   Event   Time    Duration    Thread
    Cannot save value from target back to source. BindingExpression:Path=IsDropDownOpen; DataItem='ComboBox' (Name='FavoriteFlavourCombo'); target element is 'ToggleButton' (Name='toggleButton'); target property is 'IsChecked' (type 'Nullable`1') NullReferenceException:'System.NullReferenceException: Object reference not set to an instance of an object.
    at System.Windows.Controls.ComboBox.CoerceIsSelectionBoxHighlighted(Object o, Object value)
    at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks)
    at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
    at System.Windows.DependencyObject.CoerceValue(DependencyProperty dp)
    at System.Windows.Controls.ComboBox.OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
    at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
    at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
    at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value)
    at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value)
    at System.Windows.Data.BindingExpression.UpdateSource(Object value)'    28.20s      
    

    我已将样本上传到github:https://github.com/DanMcCoy/ComboBoxBugDemo 此示例使用框架4.6.1。我正在使用Visual Studio Enterprise 2015(14.0.25425.01 Update 3)。

    GitHub回购中有一段视频证明了这个问题。

0 个答案:

没有答案