Dave
Dave

Reputation: 15016

Re-establishing WPF databinding after changing property value

I'm playing with ICollectionView right now, and am encountering a problem where I think I understand the "why", but not the "how do I fix it". :)

I have a ComboBox that's databound to an ICollectionView, and it is initially set with the following code:

NameView = CollectionViewSource.GetDefaultView( names); // names is an IEnumerable<string> that comes from a LINQ query
NameView.CurrentChanged += new EventHandler(NameView_CurrentChanged);

Everything works great until I execute a piece of code that generates a new IEnumerable<string> and sets NameView again with the same code as above. Once I do this, CurrentItem is no longer working properly.

I've run into this problem before with ObservableCollection<string> databound to ComboBoxes, and I get around the "unbinding" problem by using Clear() and Add() instead of setting the ObservableCollection<string> property to a new ObservableCollection<string>.

My questions include: 1. If I wanted to be able to just set the property to a new collection, can I re-establish databinding with the new collection somehow? If so, how? If not, can you explain the WPFisms behind why this is fundamentally not possible? 2. What's the best way to deal with changes in an ObservableCollection<string> or ICollectionView? Is my approach of just Clearing and Adding the only way to do it?

Upvotes: 0

Views: 399

Answers (1)

Sebastian Edelmeier
Sebastian Edelmeier

Reputation: 4157

When you bind your WPF Controls to ICollectionViews (Happens when the XAML is parsed withing your InitializeComponent-call - You should really define the bindings in XAML!), the Controls subscribe to the required events published by your collection (e.g. CollectionChanged).

Your collection property is just a reference to a memory address. When you bend this to a new collection (i.e. a new address), the DataBinding won't notice. You can't expect the original Collection to publish something like "IAmOuttaHere", and clearly the controls wouldn't listen to a new collection saying "I'm the new guy". But if I see this correctly, your snippet does nothing but add an eventhandler to the CurrentChanged (meaning your observe when some other item in the Combobox is being selected)

Binding is all about notification, so - as long as you don't tell your controls that the collection has been exchanged, they will stick to the initial collection. Please try to implement INotifyPropertyChanged like so:

    public class ViewModel : INotifyPropertyChanged
{
    private ICollectionView myCollection;

    public ICollectionView MyCollection
    {
        get
        {
            return this.myCollection;
        }
        set
        {
            this.myCollection = value;
            this.OnPropertyChanged("MyCollection");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void ExchangeCollection()
    {
        this.MyCollection = new CollectionView(....)
    }

}

Any bindings should be made to MyCollection. Although, personally, I don't define ICollectionViews myself, since they are not really as nice to work with as for example a nifty IList and they are auto-wrapped around any collection anyway as soon as a binding is defined.

Hope this helps

Sebi

Upvotes: 1

Related Questions