Update ObservableCollection where the items are received from another List

1k views Asked by At

I want to display all my CONTACTS in a ItemsControl dynamically. I have a List Contacts in my Logic (this one gets updated if someone removed me or if someone accepted my request) and I've added this List to a ObservableCollection<> which is bound to the ListBox.

C#

Contacts = new ObservableCollection<Contact>(MyLogic.Current.Contacts);

XAML

<ItemsControl ItemsSource="{Binding Contacts}" x:Name="MainPanel">

And here's the problem: When I want to add a contact to my Contacts LIST, the ObservableCollection doesn't get updated

MyLogic.Current.Contacts.Add(new Contact("Fred", true));
3

There are 3 answers

0
Bahman_Aries On BEST ANSWER

This is not the best solution but if you want to see where the problem is, the following code updates your UI:

var newContact = new Contact("Fred", true));
MyLogic.Current.Contacts.Add(newContact);
Contacts.Add(newContact);

A better solution is when MyLogic.Current.Contacts changes notify your UI via events.

Edit:

The problem is that I can only update the LIST and not the ObservableCollection(the list itself is in a different project)... so I need a way to update the GUI when that LIST is updated

To notify UI when ever your data changes you can use events as follow:

First define an EventArgs which shows newly added items like this:

public class ModelAddedEventArgs<TModel> : EventArgs
{
    public ModelAddedEventArgs(TModel newModel)
    {
        NewModel = newModel;
    }

    public TModel NewModel { get; set; }
}

Then define an EventHandler in your MyLogic calss as follow:

public event EventHandler<ModelAddedEventArgs<Contact>> ContactAdded;

    public void AddModel(Contact model)
    {
        // first add your contact then:
        if (ActivityGroupAdded != null)
            ActivityGroupAdded(this, new ModelAddedEventArgs<Contact>(model));
    }

And finally use your EventHandler to notify UI:

    private void YourUIConstructor()
    {
        MyLogic += OnContactAdded;
    }
    private void OnContactAdded(object sender, ModelAddedEventArgs<Contact> e)
    {
        Contacts.Add(e.NewModel);
    }
4
Kirill Bestemyanov On

ObservableCollection is not work with source List. When you create it from existing List it only copies elements from it to inner storage. So, you should add elements to ObservableCollection itself to get what you want etc.

1
Mike Eason On

The problem you are having is that you are expecting the ObservableCollection to be automatically updated when you add to your List. This is not true.

When you instantiate your ObservableCollection, you are taking a copy of your List, not a reference to the list itself.

Therefore, when you add a new item, you should add to your ObservableCollection, not your List. Or both. But I can't see why you would need both, I would recommend ditching your List altogether.