views:

19

answers:

1

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?

A: 

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

Sebastian Edelmeier
Thanks, I understand the why, but I think you've shown me something important here. I failed to use INotifyPropertyChanged. Oops! I'll give it a try and let you know how it goes.
Dave