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);
}
}
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 of BindingList<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");
}
}
You can use Task, Async and await, where is some code which insert an element in a listbox each second without blocking UI.
In your case, you have to return the data from backend asynchronously.
public async void LoadItemsAsync()
{
for (int i = 0; i < 10; i++)
listBox1.Items.Add(await GetItem());
}
public Task<string> GetItem()
{
return Task<string>.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return "Item";
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.