2016-07-04 269 views
1

使用数据表作为datagridview的数据源工作得非常好,但是,当列正在排序时,我无法获取Dgv_SortCompare事件。主要问题是dgv值中的(纯粹)数值列列中的数值被排序为文本,例如, 1211.6小于89.7DataGridView的SortCompare事件不会触发动态添加到TabControl

In Button1: 

Dim datagridview1 As New DataGridView 
datagridview1.AutoSize = True 
datagridview1.AutoResizeRows() 
datagridview1.AutoResizeColumns() 
datagridview1.ClearSelection() 
DoubleBuffered(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.Dock = DockStyle.Fill 

datagridview1.Refresh() 
datagridview1.VirtualMode = False 

Dim dgv As New DGVCREATE(datagridview1, dataarray, columnheaders, rowheaders, InputFeatureNames, InputObjectNames) 

TabControl2.SelectedTab = TabControl2.TabPages.Item(0) 
TabControl2.TabPages(0).Controls.Clear() 
AddHandler() datagridview1.SortCompare, AddressOf dgv_SortCompare 
TabControl2.TabPages(0).Controls.Add(datagridview1) 
AddHandler CType(TabControl2.TabPages(0).Controls(0), DataGridView).SortCompare, AddressOf Me.dgv_SortCompare 



Public Class DGVCREATE 

    Sub New(ByRef dgv As DataGridView, ByVal dataarray(,) As Object, ByVal columnheaders() As String, ByVal rowheaders() As String, ByVal FieldNames() As String, ByVal RowNames() As String) 

     dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing 

     ' Create the output table. 
     GetResultsTable(rxdataarray, columnheaders, rowheaders, FieldNames, RowNames) 

     'new trial code 
     dgv.AutoGenerateColumns = False 

     dgv.DataSource = Form1.MainDataTable 
     dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill 

     'Set Column FillWeight in very large DGVs in order to prevent exception related to “Sum of FillWeight exceeds 65000” 

     For i As Integer = 0 To Form1.MainDataTable.Columns.Count - 1 
      Dim Column As New DataGridViewTextBoxColumn 
      Column.Name = Form1.MainDataTable.Columns(i).ColumnName 
      Column.DataPropertyName = Form1.MainDataTable.Columns(i).ColumnName 
      Column.HeaderText = Form1.MainDataTable.Columns(i).ColumnName 
      Column.FillWeight = 20 
      Column.MinimumWidth = 20 
      dgv.Columns.Add(Column) 
     Next i 

     For i As Integer = 0 To dgv.Columns.Count - 1 
      If InputFeatureType(i + 1) = 1 Then 
       dgv.Columns(i).ValueType = GetType(Int64) 
       dgv.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic 
      End If 
      If InputFeatureType(i + 1) = 2 Then 
       dgv.Columns(i).ValueType = GetType(Double) 
       dgv.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic 
      End If 
      If InputFeatureType(i + 1) = 3 Then 
       dgv.Columns(i).ValueType = GetType(Double) 
       dgv.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic 
      End If 
      If InputFeatureType(i + 1) = 4 Then 
       dgv.Columns(i).ValueType = GetType(String) 
       dgv.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic 
      End If 
     Next i 

     dgv.AutoSize = True 
    End Sub 

    Public Sub GetResultsTable(ByVal dataarray(,) As Object, ByVal columnheaders() As String, ByVal rowheaders() As String, ByVal fieldnames() As String, ByVal rownames() As String) 
     Form1.MainDataTable.Clear() 
     Form1.MainDataTable.Rows.Clear() 
     Form1.MainDataTable.Columns.Clear() 
     ' Loop through all process names. 
     For j As Integer = 0 To UBound(columnheaders) - 1 
      ' The current process name. 
      ' Add the program name to our columns. 
      Form1.MainDataTable.Columns.Add(fieldnames(j + 1)) 
      'Form1.MainDataTable.Columns.Add(fieldnames(j + 1)) 
      ' Keep adding rows until we have enough. 
      Do While Form1.MainDataTable.Rows.Count < UBound(rowheaders) 
       Form1.MainDataTable.Rows.Add() 
      Loop 
      ' Add each item to the cells in the column. 
      For i As Integer = 0 To UBound(rowheaders) - 1 
       Form1.MainDataTable.Rows(i)(j) = dataarray(i, j) 
      Next i 
     Next j 
    End Sub 
End Class 

有什么建议吗?

+0

不能重复e - DGV中需要哪些帮助进行分类? – Plutonix

+0

正在对数值进行排序,就好像它们是字符串值一样,即将1,220.7视为小于89.7。 – wrtsvkrfm

+0

我怀疑是因为你正在存储字符串。您不需要为每个单元格设置'ValueType',只需设置'dgv.Columns(n).ValueType = ...'来设置整个列。我很肯定你需要在添加任何数据之前做到这一点。 ''D“'指定日期格式,请尝试”Nx“,其中x是位数。如果“*”是一个包含数字的数字列,那么“D”格式应该会导致一个'DataError'。鉴于实际数字,默认排序应该可以正常工作。也许显示它是如何创建和填充的 – Plutonix

回答

1

你有很多不需要的代码。首先,你想避免装箱你的数据As Object,因为它阻止像DGV这样的东西看到它是什么类型。 A DataTable完全能够存储输入的数据。如果你有,你可以创建一个类表现得像一个DTO:

Public Class DataItem 
    Public Property Able As Int64 
    Public Property Baker As Double 
    Public Property Charlie As Double 
    Public Property Delta As String 
End Class 

由于DataTable可以容纳多种类型,代替DataArray使用,并避免数据hopscotching有它的方式:

Private dtData As DataTable 
... 
' create it somewhere 
dtData = New DataTable 
dtData.Columns.Add("Able", GetType(Int64)) 
dtData.Columns.Add("Baker", GetType(Double)) 
dtData.Columns.Add("Chanrlie", GetType(Double)) ' aka Charlie 
dtData.Columns.Add("Delta", GetType(String)) 

填充数据:

For n As Int32 = 0 To 999 
    dr = dtData.NewRow 

    dr(0) = RNG.Next()  ' random value 
    dr(1) = RNG.NextDouble() ' random 0.00 to 1.0 
    dr(2) = RNG.Next(-19, 20) + RNG.NextDouble() ' -19.xx to +19.xx 
    dr(3) = RD.GetNames(2, 35) ' 2 random names 
    ' add new row: 
    dtData.Rows.Add(dr) 
Next 

当它被填满,让DGV为您创建的列 - 它会从源中读取数据类型等:

dgv1.DataSource = dtData 
For Each dc As DataGridViewColumn In dgv1.Columns 
    Console.WriteLine(dc.ValueType) 
Next 

的DGV看到的类型和将正确排序,它们中的任何:

System.Int64
System.Double
System.Double
System.String

enter image description here

+0

Thanks Plutonix!这太棒了。你是否在使用Mersenne Twister作为'RNG'?在生成向量后,'RNG.next()'看起来像是一个随机数的C#锐利使用。 – wrtsvkrfm

+0

不,“RNG”是标准的NET“随机”类,“下一个”是标准方法。 RD是一个随机数据生成器,但名称(生成测试用的快速方法)。大多数梅森实现都从它继承,所以这些方法具有相同的名称。 – Plutonix

相关问题