如何异步填充和格式化DataGridView?

问题描述 投票:0回答:1

我正在尝试异步填充和格式化

DataGridView
。我正在使用
.Net 7

要馈送到 DGV 的数据是从 MySQL 查询异步检索的。在某些情况下,DGV 可能非常大,具有 10k+ 行和大约 150 列。通常,填充数据花费的时间较少,但格式化某些具有特定背景颜色的列以及具有不同宽度的所有列需要更多时间。整个过程冻结了整个应用程序的 UI(同一个 WinForm 或另一个,用户并行异步浏览)。

所以我的想法是如果可能的话,将下面的代码转移到完全异步运行,没有任何 UI 阻塞。

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim TabStats As New DataTable
    'Other async code for filling the table from MySQL query

    DataGridView1.DataSource = Nothing
    DataGridView1.DataSource = TabStats

    DataGridView1.Columns(0).Width = 80
    DataGridView1.Columns(1).Width = 80
    DataGridView1.Columns(2).Width = 80

    DataGridView1.Columns(0).DefaultCellStyle.BackColor = Color.Blue
    DataGridView1.Columns(1).DefaultCellStyle.BackColor = Color.Blue
    DataGridView1.Columns(2).DefaultCellStyle.BackColor = Color.Blue
End Sub

我尝试过的如下。我创建了一个用于

Sub
操作的
DGV
并将其包裹在
Async Task
中。不幸的是,UI 再次被阻止,就像上面的代码一样。

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim TabStats As New DataTable
    'Other async code for filling the table from MySQL query

    Await Task.Run(Sub() Me.Invoke(Sub() fillDgv(DataGridView1, TabStats)))
End Sub

Private Sub fillDgv(dgv As DataGridView, tab As DataTable)
    dgv.DataSource = Nothing
    dgv.DataSource = tab

    dgv.Columns(0).Width = 80
    dgv.Columns(1).Width = 80
    dgv.Columns(2).Width = 80

    dgv.Columns(0).DefaultCellStyle.BackColor = Color.Blue
    dgv.Columns(1).DefaultCellStyle.BackColor = Color.Blue
    dgv.Columns(2).DefaultCellStyle.BackColor = Color.Blue
End Sub

任何帮助将不胜感激。

multithreading vb.net winforms async-await
1个回答
0
投票

jmcilhinney 上面的建议是一个很好的建议。在绑定

DataGridView
之前设置您的
DataSource
属性。下面的示例在代码中设置属性,但您也可以使用设计器。

有两个按钮绑定不同的

DataTable
,以演示网格格式在
DataSource
刷新后仍然存在。

Public Class Form1

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    DataGridView1.AutoGenerateColumns = False
    DataGridView1.Columns.Add("Col1", "Column one")
    DataGridView1.Columns(0).DataPropertyName = "Col1"
    DataGridView1.Columns(0).DefaultCellStyle.BackColor = Color.LightBlue
    DataGridView1.Columns(0).Width = 80

    DataGridView1.Columns.Add("Col2", "Column two")
    DataGridView1.Columns(1).DataPropertyName = "Col2"
    DataGridView1.Columns(1).DefaultCellStyle.BackColor = Color.CornflowerBlue
    DataGridView1.Columns(1).Width = 70

    DataGridView1.Columns.Add("Col2", "Column three")
    DataGridView1.Columns(2).DataPropertyName = "Col3"
    DataGridView1.Columns(2).DefaultCellStyle.BackColor = Color.CadetBlue
    DataGridView1.Columns(2).Width = 60

  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim dtb As New DataTable
    dtb.Columns.Add("Col1")
    dtb.Columns.Add("Col2")
    dtb.Columns.Add("Col3")
    dtb.Rows.Add("1", "2", "3")
    dtb.Rows.Add("4", "5", "6")
    dtb.Rows.Add("7", "8", "9")

    DataGridView1.DataSource = dtb
  End Sub

  Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim dtb As New DataTable
    dtb.Columns.Add("Col1")
    dtb.Columns.Add("Col2")
    dtb.Columns.Add("Col3")
    dtb.Rows.Add("a", "b", "c")
    dtb.Rows.Add("d", "e", "f")
    dtb.Rows.Add("g", "h", "i")

    DataGridView1.DataSource = dtb
  End Sub
End Class
© www.soinside.com 2019 - 2024. All rights reserved.