Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observable collection change is not updated on UI from background but a normal property gets notification

Tags:

c#

wpf

datagrid

I have two classes

public class ConccClass<T> : ObservableCollection<T>
{
}

and

public class TestTherad: INotifyPropertyChanged
{
    private string name;
    public string Name
    { get {
        return name;
    }
        set
        {
            if (value != name)
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }
    //// the notification implemented fully here
}

Now I have created a collection of 'ConccClass' in my view model and binded it with datagrid on xaml in view.

Question When I add an item on a background thread simply without any dispacther it does not reflect in datagrid. means no item added. Todo this I have to add the item in Dispatcher. BeginInvoke. Which make sense to me.

But to update the Name of any Item I dont need dispatcher.

Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Thread.Sleep(100);
                {
                    this.Dispatcher.Invoke(() => this.Coll.Add(new TestTherad())); // **Works well**
                    //this.Coll.Add(new TestTherad()); // **does not work at all.**
                    this.Coll[0].Name = r.Next().ToString(); // ** without dispatcher works well.**
                }
            }
        });

Why such behavior?

like image 451
D J Avatar asked Nov 04 '14 09:11

D J


People also ask

What is the difference between ObservableCollection and BindingList?

The true difference is rather straightforward: ObservableCollection<T> implements INotifyCollectionChanged which provides notification when the collection is changed (you guessed ^^) It allows the binding engine to update the UI when the ObservableCollection is updated. However, BindingList<T> implements IBindingList .

Are observable collections thread safe?

ObservableCollection is the recommended collection to use for ListViews, but it isn't thread safe.

What are observable collections in C#?

An ObservableCollection is a dynamic collection of objects of a given type. Objects can be added, removed or be updated with an automatic notification of actions. When an object is added to or removed from an observable collection, the UI is automatically updated.

What is observable collection in xamarin?

This interface exposes the CollectionChanged event, an event that should be raised whenever the underlying collection changes. WPF provides the ObservableCollection<T> class, which is a built-in implementation of a data collection that implements the INotifyCollectionChanged interface.


2 Answers

The following is a short explanation:

You probably have an UI element binded to the observable collection. When you add an element to the observable collection, the UI updates to reflect changes. However, the only thread allowed to make changes to UI is the main thread.

So when you add an item to the observable collection using a background thread, the UI tries to update using the background thread, which is not allowed to make changes to UI, and an exception is thrown.

I am pretty sure that this line should throw an exception: //this.Coll.Add(new TestTherad());. Try debugging inside the task block.

When you use the dispatcher, you are making the update using the main thread, and for that reason it works.

The update to properties work, because you are just raising an event. The framework should listen for that event and make sure to dispatch it to the main thread automatically.

like image 89
Jose Ch. Avatar answered Sep 18 '22 07:09

Jose Ch.


A simple way to avoid these exceptions is to use the BindableCollection from Caliburn.Micro. This is a ObservableCollection that will automatically dispatch the CollectionChanged events to the Main Thread.

Only Use the BindableCollection in your ViewModels because the CollectionChanged events will be on the Main Thread and for performance reasons you would like to do the most of the coding on a background Thread.

like image 33
Rob B Avatar answered Sep 19 '22 07:09

Rob B