2016-07-04 18 views
1

datagridviewのデータソースとして使用すると非常にうまく動作しますが、列がソートされるときにDgv_SortCompareイベントが発生することはありません。主な問題は、dgv値の(純粋に)数値の列の数値がテキストとしてソートされていることです。 1211.6が89.7より小さいSortCompareイベントが発生しないDataGridViewの呼び出しは、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のようなものがどのようなタイプであるかを見ることができないためです。 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

Plutonixありがとう!これは素晴らしい。あなたは 'RNG'のためにメルセンヌツイスターを使用していますか? 'RNG.next()'は、ベクトルが生成された後の乱数のC#シャープな使用のように見えます。 – wrtsvkrfm

+0

いいえ、 'RNG'は標準のNET'ランダム'クラスで、 'Next'は標準的なメソッドです。 'RD'は名前のためのランダムなデータジェネレータです(テストのための素早い生成方法)。ほとんどのメルセンヌの実装はそれを継承しているので、メソッドの名前は同じです。 – Plutonix

関連する問題