0

我制作了一个自定义控件,由一些网格、堆栈面板和文本块组成。我想将其用作 ListBox 项。我正在使用它在列表的每个项目中显示多行信息,就像它在图像中显示的那样。该控件的名称是 ItemDetail。

列表框的自定义控件

为了填写列表,我单击上面的每个按钮,这些按钮会进行 SQL 查询(查询有时可能需要大约 5 秒,并且用户界面已冻结,这一点非常明显)。

为了解决这个问题,我使用 BackgroundWorker 进行 SQL 查询,并在每次返回查询的结果行时报告进度。

private void Departamento_Click(object sender, MouseButtonEventArgs e)
    {
        Elementos_Lista.Items.Clear();
        BackgroundWorker _worker = new BackgroundWorker();
        _worker.WorkerReportsProgress = true;
        _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);

        _worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
           //SQL query
           reglas.Consulta("cerrado='0' and grupo='3' order by fecha desc");   

            foreach (DataRow dr in reglas.Entidad.tabla.Rows)
            {
                _worker.ReportProgress(0, dr);
            }

        };
        _worker.RunWorkerAsync();
    }

我正在使用 BackgroundWorker 的 IsProgressChanged 事件将数据添加到 ItemDetail 的实例,然后将其添加到 ListBox。

 void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ItemDetail item = new ItemDetail((DataRow)e.UserState);
        Elementos_Lista.Items.Add(item);
    }

这样,操作花费的时间少了很多,但它仍然冻结,这是由于在返回查询的每一行后必须进行 UI 刷新。BackgroundWorker 不允许我在单独的线程中将数据添加到 ItemDetail 控件,因为它不是 UI 线程。

有没有一种方法可以加快一次渲染大量控件的过程,或者将它们以较小的批次添加到列表中,这样 UI 在完成填充列表之前似乎不会完全没有响应?

4

1 回答 1

2

只需将数据添加到ObservableCollection应该绑定到您的列表控件并让它通过数据模板生成控件,如果您有虚拟化,则不会立即创建不必要的控件(滚动出视图的控件),这应该会使操作更快.

于 2012-04-20T15:37:38.900 回答