私は1つの2D配列、つまりx(、)As Objectを使って作業しています。これは、ユーザーが開いた長方形のデータファイルに基づいています。 x(、)の内容は、ほとんどが数値の単精度または倍精度の実数と整数です。したがって、配列は、x(100,100)から例えば100までの次元を有することができる。 x(100000,1000)。VB.NET - DataGridViewのDataSourceであるLarge DataTableを高速に更新するには?
datagridviewは動的に作成され、DGVCREATEクラスの呼び出しを介して更新されます。
datagridviewで使用されるデータソースのサイズを小さくする試みとして、datagridview1.scroll用のAddHandlerがあります。これにより、ユーザーがdatagridviewをスクロールすると、左上のセル行と列arがエコーバックされ、 x(、)配列から次の20列と次の50行をDataTableに追加しようとします。DataTableは、datagridviewに表示されているデータを更新します。しかし、これは動作しません。
1つの質問DataTableにユーザーが入力した配列全体を入力すると、datagridview1を設定して、たとえば50行と20列だけが表示範囲に追加されるようにすることができます。ユーザーが配列内のどこにいるかをスクロールしないで、アレイ全体をDataTableに入れると、このコードはうまく動作しますが、追加が必要な計算更新に続いて列を追加するときにDataTableを更新するのに時間がかかりますより多くのフィールドの換言すれば、例えばDataTableの1000行と50個のフィールドとx(、)に加えられた20個の列[つまり、Redim Preserve x(行、50 + 20)]を使用してDataTableを更新すると、既に1000の行と50の列がある場合、20の列をDataTableに追加します。
'In a global module:
Public MainDataTable As New DataTable
Public FieldType() As Byte ' Byte array to denote the type of field (object, double, long, string, etc.)
Sub showdgv()
Dim x(1000, 100) As Object
Dim columnheaders(100) As String
Dim rowheaders(1000) As String
Dim fieldnames(100) As String
Dim rownames(1000) As String
For i as Integer = 0 To 999
For j As Integer = 0 to 99
x(i, j) = Rnd()
Next
Next
'Dynamically create a datagridview
Dim datagridview1 As New DataGridView
Me.Controls.Add(datagridview1)
datagridview1.AutoSize = True
datagridview1.AutoResizeRows()
datagridview1.AutoResizeColumns()
datagridview1.ClearSelection()
DoubleBufferedDGV(datagridview1, True)
datagridview1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
Dim dgvColumnHeaderStyle As New DataGridViewCellStyle()
dgvColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
datagridview1.ColumnHeadersDefaultCellStyle = dgvColumnHeaderStyle
datagridview1.AllowUserToAddRows = False
datagridview1.ScrollBars = ScrollBars.Both
datagridview1.Refresh()
datagridview1.Dock = DockStyle.Fill
AddHandler datagridview1.Scroll, AddressOf Me.DGV1_Scroll
'Instantiate the class object to update the DGV by loading the DataTable with the contant of the array x(,)
Dim dgv As New DGVCREATE(datagridview1, x, columnheaders, rowheaders, FieldNames, RowNames)
End Sub
Public Class DGVCREATE
Dim x(,) As Object
Dim columnheaders() As String
Dim rowheaders() As String
Dim fieldnames() As String
Dim rownames() As String
Sub New(ByRef dgv As DataGridView, ByVal x(,) As Object, ByVal columnheaders() As String, ByVal rowheaders() As String, ByVal FieldNames() As String, ByVal RowNames() As String)
Dim main As Form1 = CType(Application.OpenForms(0), Form1)
dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
GetResultsTable(x, columnheaders, rowheaders, FieldNames, RowNames)
'new trial code
dgv.AutoGenerateColumns = True
'Application.DoEvents()
dgv.DataSource = main.MainDataTable
dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
For i As Integer = 0 To main.MainDataTable.Columns.Count - 1
Dim Column As New DataGridViewTextBoxColumn
Column.Name = main.MainDataTable.Columns(i).ColumnName
Column.DataPropertyName = main.MainDataTable.Columns(i).ColumnName
Column.HeaderText = main.MainDataTable.Columns(i).ColumnName
Column.FillWeight = 70
Column.MinimumWidth = 70
dgv.Columns.Add(Column)
Next i
dgv.AutoSize = True
End Sub
Public Sub GetResultsTable(ByVal x(,) As Object, ByVal columnheaders() As String, ByVal rowheaders() As String, ByVal fieldnames() As String, ByVal rownames() As String)
Dim main As Form1 = CType(Application.OpenForms(0), Form1)
main.MainDataTable.Clear()
main.MainDataTable.Rows.Clear()
main.MainDataTable.Columns.Clear()
' Loop through all process names.
For j As Integer = dgvbegincol To dgvbegincol + 30 ' 0 To UBound(columnheaders) - 1
' The current process name.
' Add the program name to our columns.
Try
If FieldType(j + 1) = 0 Then main.MainDataTable.Columns.Add(fieldnames(j + 1), GetType(Object))
If FieldType(j + 1) = 1 Then main.MainDataTable.Columns.Add(fieldnames(j + 1), GetType(Double))
If FieldType(j + 1) = 2 Then main.MainDataTable.Columns.Add(fieldnames(j + 1), GetType(Long))
If FieldType(j + 1) = 3 Then main.MainDataTable.Columns.Add(fieldnames(j + 1), GetType(Long))
If FieldType(j + 1) = 4 Then main.MainDataTable.Columns.Add(fieldnames(j + 1), GetType(String))
Catch ex As Exception
If InStr(ex.Message, "column name") > 0 Then
Try
If FieldType(j + 1) = 0 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Object))
If FieldType(j + 1) = 1 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Double))
If FieldType(j + 1) = 2 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Long))
If FieldType(j + 1) = 3 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Long))
If FieldType(j + 1) = 4 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(String))
fieldnames(j + 1) = fieldnames(j + 1) & "_" & varsuffixvalue.ToString
Catch ex1 As Exception
If InStr(ex1.Message, "column name") > 0 Then
varsuffixvalue += 1
If FieldType(j + 1) = 0 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Object))
If FieldType(j + 1) = 1 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Double))
If FieldType(j + 1) = 2 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Long))
If FieldType(j + 1) = 3 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(Long))
If FieldType(j + 1) = 4 Then main.MainDataTable.Columns.Add(fieldnames(j + 1) & "_" & varsuffixvalue.ToString, GetType(String))
fieldnames(j + 1) = fieldnames(j + 1) & "_" & varsuffixvalue.ToString
End If
End Try
End If
End Try
Do While main.MainDataTable.Rows.Count < UBound(rowheaders)
Dim myRow As DataRow
myRow = main.MainDataTable.NewRow()
main.MainDataTable.Rows.Add(myRow)
Loop
' Add each item to the cells in the column.
For i As Integer = dgvbeginrow To dgvbeginrow + 50 ' 0 To UBound(rowheaders) - 1
main.MainDataTable.Rows(i)(j) = If(x(i, j), CObj(DBNull.Value))
Next i
Next j
dgvThreadDone.Set()
End Sub
End Class
Sub DGV1_Scroll(sender As Object, e As ScrollEventArgs)
Dim x(,) As Object
Dim rowheaders() As String, columnheaders() As String
rowheaders = RowNames.Clone
columnheaders = FieldNames.Clone
For Each c In Me.Controls
If TypeOf (c) Is DataGridView Then
'Public dgvbeginrow, dgvendrow, dgvbegincol, dgvendcol As Integer
dgvbeginrow = c.FirstDisplayedCell.RowIndex
dgvbegincol = c.FirstDisplayedCell.ColumnIndex
Dim dgv As New DGVCREATE(c, x, columnheaders, rowheaders, FieldNames, RowNames)
End If
Next
End Sub
私はあなたが 'DataTable'とあなたの2次元配列を交換をお勧めします。 – SSS