简体   繁体   English

在保持 UI 响应的同时将许多项目添加到 ListBox

[英]Add many items to ListBox while keeping the UI resposive

I am trying to update a ListBox with large amount of data and keep the UI responsive at the same time.我正在尝试使用大量数据更新 ListBox 并同时保持 UI 响应。

Here is the code I am using to achieve this, going through 10000 items, collecting them into a 100-item batch and then inserting these 100 items in one go so that I avoid UI update each time a single item is added, but unfortunately the code does not work and the UI is updated only after all the 10000 items are actually added to ListBox.这是我用来实现这一点的代码,遍历 10000 个项目,将它们收集到一个 100 个项目的批次中,然后将这 100 个项目插入一个 go 以便我避免每次添加单个项目时更新 UI,但不幸的是代码不起作用,只有在将所有 10000 个项目实际添加到 ListBox 后才会更新 UI。

在此处输入图像描述

public partial class Form1 : Form
{
    private SynchronizationContext synchronizationContext;

    public Form1()
    {
        InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        synchronizationContext = SynchronizationContext.Current;

        await Task.Run(() =>
        {
            ConcurrentDictionary<int, int> batch = new ConcurrentDictionary<int, int>();
            int count = 0;
            for (var i = 0; i <= 10000; i++)
            {
                batch[i] = i;
                count++;
                if (count == 100)
                {
                    count = 0;
                    UpdateUI(batch);
                    batch = new ConcurrentDictionary<int, int>();
                }

                
            }
        });
    }

    private void UpdateUI(ConcurrentDictionary<int, int> items)
    {
        synchronizationContext.Post(o =>
        {
            listBox1.SuspendLayout();
            foreach (var item in items)
            {
                listBox1.Items.Add(item.Value);
            }

            listBox1.ResumeLayout();

        }, null);
    }
}

You don't need a multithreading approach in order to update the UI.您不需要多线程方法来更新 UI。 All you need is to suspend the painting of the ListBox during the mass insert, by using the ListBox.BeginUpdate and ListBox.EndUpdate methods:您只需使用ListBox.BeginUpdateListBox.EndUpdate方法在批量插入期间暂停绘制ListBox

private void button1_Click(object sender, EventArgs e)
{
    listBox1.BeginUpdate();
    for (var i = 1; i <= 10000; i++)
    {
        listBox1.Items.Add(i);
    }
    listBox1.EndUpdate();
}

The Control.SuspendLayout and Control.ResumeLayout methods are used when you add controls dynamically in a flexible container, and you want to prevent the controls from jumping around when each new control is added. Control.SuspendLayoutControl.ResumeLayout方法用于在灵活容器中动态添加控件,并且希望在添加每个新控件时防止控件跳来跳去。

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

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