1
votes

i have a mvvm app that the main window is a tab control. i use the itemssource to bind items to the combo box, everything works fine until i go to another tab and for some reason the selected item of the combo box getting the null value, any ideas ?

the binding is twoway updatesource onpropertychanged and the property is type of observablecollection

5
Could you post the relevant XAML and/or C#? That could help us to figure out what you're trying to do and to narrow down the problem.Andy

5 Answers

2
votes

I had same problem before. And the solution is that make sure Itemsource attribute of comboBox in XAML has not been declared before SelectedValue attribute. It should work then.

2
votes

It is just necessary to work on a ObservableCollection and to load only as AddRange (not use 'Add')

When we load the data as:

foreach (object item in items)
{
    MyList.Add(item); // Where MyList is a ObservableCollection
}

Then after adding of the first element the ObservableCollection call OnCollectionChanged. Then the ComboBox will try to select the SelectedValue and return 'null' when can't find this element.

It can solve a problem:

using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

namespace System.Collections.ObjectModel
{
    /// <summary> 
    /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class ObservableCollectionEx<T> : ObservableCollection<T>
    {
        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
        /// </summary> 
        public ObservableCollectionEx()
            : base() { }

        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
        /// </summary> 
        /// <param name="collection">collection: The collection from which the elements are copied.</param> 
        /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
        public ObservableCollectionEx(IEnumerable<T> collection)
            : base(collection) { }

        /// <summary> 
        /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
        /// </summary> 
        public void AddRange(IEnumerable<T> collection)
        {
            //
            // Add the items directly to the inner collection
            //
            foreach (var data in collection)
            {
                this.Items.Add(data);
            }

            //
            // Now raise the changed events
            //
            this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));

            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

    }
}
0
votes

I have an mvvm app with almost exactly the same scenario. The main window has a tab control. There is a tab containing a combobox. The combobox itemsource is bound to an IList (in the view model) and the Selected value is bound to a property in the view model implementing INotifyPropertyChanged.

<ComboBox ItemsSource="{Binding AllowedJudges}"  
                  SelectedValue="{Binding SelectedJudge, UpdateSourceTrigger=PropertyChanged}"  >

When selecting another tab, the view model's property bound to the SelectedValue mysteriously gets set to null. I'm able to handle it by not allowing the SelectedValue-bound property to be set to null:

 public Judge SelectedJudge
  {
     get { return selectedJudge; }
     set
     {
        if(selectedJudge==value || value==null) return;
        selectedJudge = value;
        OnPropertyChanged("SelectedJudge");
        updateViewData();
     }
  }

However, it's not clear to me why a tab pane becoming invisible implies a value in a combobox there becomes deselected....

0
votes

If for some Reason the BindingSource of the ItemsSource does no longer contain the SeletedItem (because it's re-initialized or whatever), then the SelectedItem can be reset to default, i.e. null. From your example I can't tell why this should happen, but that maybe because you just missed adding some more environmental code.

0
votes

It`s may be problem of your viewmodel ierarchy. For example, if both ends of your Binding are dependency properties and ownertype property is not tied to a particular class (for example, set the parent class), this dependency property will be used by all the inheritors together. Bad design