我只使用一个2D数组,即x(,)As Object,它基于用户打开的矩形数据文件。 x(,)的内容主要是数字单精度或双精度实数和整数。因此,阵列可以具有从x(100,100)到例如x(100,100)的尺寸。 X(100000,1000)。
datagridview是动态创建的,并通过调用DGVCREATE类进行更新。
作为尝试减少datagridview使用的数据源的sizer,有一个datagridview1.scroll的AddHandler,这样当用户滚动datagridview时,左上角的单元格行和列将被删除,然后是尝试将x(,)数组中接下来的20列和接下来的50行添加到DataTable中,DataTable假定更新datagridview中显示的数据。但这不起作用。
一个问题,如果我使用用户输入的整个数组填充DataTable,如何设置datagridview1,以便只将50行和20列添加到可见范围。如果没有滚动的addhandler来挑选用户在数组中的位置,并且将整个数组填充到DataTable中,这段代码工作正常,但是在计算更新后添加列时需要很长时间来更新DataTable,这需要添加更多领域。换句话说,当有例如DataTable中有1000行和50个字段,另外20列添加到x(,)[即Redim Preserve x(行,50 + 20)],然后更新DataTable,需要很长时间才能添加额外的当DataTable已有1000行和50列时,它们有20列。
'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
答案 0 :(得分:1)
我认为使用DataTable
填充DataGridView
可以获得更好的结果:
Public Class Form1
'For this example, add a DataGridView and Button under it
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim dtb As New DataTable()
'Start with 50 columns and 1000 rows
For intCol As Integer = 0 To 49
dtb.Columns.Add("Col" & intCol.ToString("000"))
Next intCol
For intRow As Integer = 0 To 999
Dim drw As DataRow = dtb.NewRow
For intCol As Integer = 0 To 49
drw(intCol) = Rnd()
Next intCol
dtb.Rows.Add(drw)
Next intRow
DataGridView1.DataSource = dtb
DataGridView1.Anchor = AnchorStyles.Top Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Bottom
Button1.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Add 20 columns
Me.Cursor = Cursors.WaitCursor
Dim dtb As DataTable = DirectCast(DataGridView1.DataSource, DataTable)
Dim intOldColumnCount As Integer = dtb.Columns.Count
For intCol As Integer = intOldColumnCount To intOldColumnCount + 20
dtb.Columns.Add("Col" & intCol.ToString("000"))
Next intCol
For intRow As Integer = 0 To dtb.Rows.Count - 1
Dim drw As DataRow = dtb.Rows(intRow)
For intCol As Integer = intOldColumnCount To intOldColumnCount + 20
drw(intCol) = Rnd()
Next intCol
Next intRow
Me.Cursor = Cursors.Default
End Sub
End Class