2016-07-04 72 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

相關問題