简体   繁体   English

刷新UI以反映添加到列表中的项目

[英]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. 当我的UI显示时,数据将在后端传递并添加到List<string> ,我将依次在我的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? 问题: 如何在我的UI后面重复运行此方法而不在循环中锁定我的UI?

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. 可以使用BindingList<T>ObservableCollection<T>并在列表更改时接收通知,而不是使用循环或时间间隔来监视列表。

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> . 然后,您可以更新事件处理程序中的用户界面,该事件处理程序已达到BindingList<T> ListChanged事件或ObservableCOllection<T> CollectionChanged事件。

Example

Here is an example based on ObservableCollection<string> . 这是一个基于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. 您可以使用Task,Async和await,其中一些代码每秒在列表框中插入一个元素而不阻止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";
        });
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM