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

C# 刷新UI以反映添加到列表中的项目,c#,winforms,background,C#,Winforms,Background,在显示我的UI时,数据在后端传递,并添加到我希望在UI上显示的列表中 我见过几个使用后台工作程序的示例,但是由于我如何布局用户控件并以编程方式构建它们,我无法访问实际的组件 问题:如何在UI后面重复运行此方法而不将UI锁定在循环中? public void UpdatePanel() { foreach (var item in list) { AddMethod(item); } } 您可以使用Task、Async和await,其中有些代码每秒在列表框

在显示我的UI时,数据在后端传递,并添加到我希望在UI上显示的
列表中

我见过几个使用后台工作程序的示例,但是由于我如何布局用户控件并以编程方式构建它们,我无法访问实际的组件

问题:如何在UI后面重复运行此方法而不将UI锁定在循环中?

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

您可以使用Task、Async和await,其中有些代码每秒在列表框中插入一个元素,而不会阻塞UI

在您的情况下,必须从后端异步返回数据

    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";
        });
    }
public异步void LoadItemsAsync()
{
对于(int i=0;i<10;i++)
listBox1.Items.Add(wait-GetItem());
}
公共任务GetItem()
{
返回Task.Factory.StartNew(()=>
{
睡眠(1000);
返回“项目”;
});
}

如果可能,您可以使用或,在列表更改时接收通知,而不是使用循环或时间间隔来监视列表

然后,您可以在事件处理程序中更新用户界面,该事件处理程序附加到
ListChanged
event of
bindingslist
CollectionChanged
event of
observedcollection

示例

下面是一个基于
可观测采集的示例

可观察收集列表;
私有void Form1\u加载(对象发送方、事件参数e)
{
列表=新的ObservableCollection();
list.CollectionChanged+=列表_CollectionChanged;
列表。添加(“第1项”);
列表。添加(“第2项”);
移除列表(0);
列表[0]=“新项目”;
}
无效列表\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
if(e.Action==NotifyCollectionChangedAction.Add)
{
var items=string.Join(“,”,e.NewItems.Cast());
Show(string.Format(“{0}”添加),items));
}
else if(e.Action==NotifyCollectionChangedAction.Remove)
{
var items=string.Join(“,”,e.OldItems.Cast());
Show(string.Format(“{0}”已删除),items);
}
else if(e.Action==NotifyCollectionChangedAction.Replace)
{
var oldItems=string.Join(“,”,e.oldItems.Cast());
var newItems=string.Join(“,”,e.newItems.Cast());
Show(string.Format(“{0}”替换为“{1}”,oldItems,newItems));
}
其他的
{
MessageBox.Show(“重置或移动”);
}
}

尝试查找
BackgroundWorker
Task
类似于
async Task.Run(()=>{your stuff};
沿着
Dispatcher.BeginInvoke(…)
更新一些进度条?我已经看到了几个使用后台工作人员的示例,但是由于我如何布局用户控件并以编程方式构建它们,我无法访问实际组件。为什么?您可以简单地在代码中创建它。
列表的类型是什么?
?类型列表这似乎正是我需要做的。。。我的问题是实际启动这个方法。我是在窗体的构造函数中运行它,它会自动运行,还是会继续运行?您的后端调用必须返回一个任务,这就是我使用Wait的原因,它从任务中获取结果值,也在您的代码中,您必须修饰调用您的方法这是一个比我最初思考的领域更好的解决方案。谢谢你的解释和回答。@RezaAghaei
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");
    }
}