0perator 0perator - 3 months ago 21
C# Question

Refreshing a UI to reflect items added to a list

While my UI is displayed, data is being passed in the back end and added to a

List<string>
that I would in turn like to display on my UI.

I've seen several examples using background workers however I don't have access to the actual component due to how I layout my User Controls and programmatically build them.

Question: How can I run this method repeatedly behind my UI without locking up my UI in a loop?

public void UpdatePanel()
{
foreach (var item in list)
{
AddMethod(item);
}
}

Answer

Instead of using a loop or time intervals to monitor a list, as an option when possible, you can use a BindingList<T> or ObservableCollection<T> and receive notification when list changes.

Then you can update user interface in the event handler which you attaced to ListChanged event ofBindingList<T> or CollectionChanged event of ObservableCOllection<T>.

Example

Here is an example based on ObservableCollection<string>.

ObservableCollection<string> list;
private void Form1_Load(object sender, EventArgs e)
{
    list = new ObservableCollection<string>();
    list.CollectionChanged += list_CollectionChanged;
    list.Add("Item 1");
    list.Add("Item 2");
    list.RemoveAt(0);
    list[0] = "New Item";
}
void list_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        var items = string.Join(",", e.NewItems.Cast<String>());
        MessageBox.Show(string.Format("'{0}' Added", items));
    }
    else if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        var items = string.Join(",", e.OldItems.Cast<String>());
        MessageBox.Show(string.Format("'{0}' Removed", items));
    }
    else if (e.Action == NotifyCollectionChangedAction.Replace)
    {
        var oldItems = string.Join(",", e.OldItems.Cast<String>());
        var newItems = string.Join(",", e.NewItems.Cast<String>());
        MessageBox.Show(string.Format("'{0}' replaced by '{1}'", oldItems, newItems));
    }
    else
    {
        MessageBox.Show("Reset or Move");
    }
}