0

I have a bound DataGridView that displays file sizes:

133 kb
20 Mb
43.11 Mb
2.23 Gb

etc

I would usually ensure the column type was decimal in the DataSource (Datatable here) but the value contains size designations preventing this. How can I sort them both numerically while abiding by the data units?

0

1 Answer 1

1

This is what I have now.

<!-- language: lang-vb-->
     Dim d As New DataTable()

    Dim c As New DataColumn("Size")
    c.DataType = GetType(Integer)

    Dim c2 As New DataColumn("SizeInUnits")
    c2.DataType = GetType(String)

    d.Columns.Add(c)
    d.Columns.Add(c2)

    Dim strFileSize As String = ""
    Dim di As New IO.DirectoryInfo("C:\temp")
    Dim aryFi As IO.FileInfo() = di.GetFiles("*.*")


    For Each fi As IO.FileInfo In aryFi
        Dim r As DataRow = d.NewRow()
        r(0) = fi.Length
        r(1) = GetSizeInUnits(fi.Length)
        d.Rows.Add(r)
    Next

    d.DefaultView.Sort = "Size ASC"
    DataGridView1.DataSource = d
    DataGridView1.Columns(0).Visible = False

    'New Code Here, Don't Auto Sort. We will sort the data ourselves in event
    'DataGridView1_ColumnHeaderMouseClick. You will have to do some additional work
    'to determin the sort direction. i.e. If Current Sort Order is ASC, the sort DESC 
    'and vice versa
    DataGridView1.Columns(1).SortMode = DataGridViewColumnSortMode.Programmatic

     Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As System.Object, ByVal e As        System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
            DataGridView1.Sort(DataGridView1.Columns(0), System.ComponentModel.ListSortDirection.Descending)
     End Sub

    Private Function GetSizeInUnits(ByVal size As Double) As String
    Dim sizeKB As String = "KB"
    Dim sizeMB As String = "MB"
    Dim sizeGB As String = "GB"

    If (size < 1000000) Then
        Return size / 1000 & sizeKB
    End If

    If (size > 1000000 AndAlso size < 1000000000) Then
        Return size / 1000000 & sizeMB
    End If

    If (size > 1000000000) Then
        Return size / 1000000000 & sizeGB
    End If

    End Function
Sign up to request clarification or add additional context in comments.

5 Comments

I'm using System.IO.FileInfo to generate a list of files and their attributes (into a datatable). This returns the file value in bytes which I pass through a function to convert it to a readable value before populating a column in the datatable.
If I may suggest another possible solution which would require only one column on DataTable. You could use a Dictionary Object. Using Lenght as Key and Unit Size as value. You could then sort the Dictionary to return a list in the order that you want. Iterate this list and add to the datatable.
Will clicking the DataGridView header for SizeInUnits not remove the sort on the hidden column though?
We are setting the order by programtically. so clicking the header will have no affect. its the click event that sets the order. have you tried the code above.
Hi, The changes work well - Sort on ColumnHeaderMouseClick. Do you know if it's possible to display the sort direction arrow on the header? That seems to be the only down side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.