views:

115

answers:

2

I have a page which lists all the files in a particular folder (all PDFs), using a data-table and gridview.

I'm currently sorting this table by the filename (by using a dataview), which isn't that helpful, and I want the gridview of files sorted by the file created or file modified date (as recorded in Windows).

If that's not possible, a second option would be to extract the date from the file name string (no problem doing that), and sort the dataview/datatable or gridview based on that. Example Filename: DailySalesReport-1-15-2010. My only hangup with this is how do I sort on date, when it's a string value? Convert to date? How would I sort the whole dataset based on this converted value?

Thanks for any ideas!

Protected Sub PageLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        Dim dt As New DataTable()
        dt.Columns.Add("Daily Reports", Type.[GetType]("System.String"))

        For Each name As [String] In System.IO.Directory.GetFiles(Server.MapPath("~\reports\pdf\")) '"
                dt.Rows.Add(New Object() {name})
        Next

        Dim dv As DataView = dt.DefaultView
        dv.Sort = dt.Columns(0).ToString + " " + "desc"
        dt = dv.ToTable

        Me.gvDaily.DataSource = dt
        Me.gvDaily.DataBind()

    End If
End Sub



Protected Sub gvDaily_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)

    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim hl As New HyperLink()
        hl.NavigateUrl = "~\reports\pdfs\" + e.Row.Cells(0).Text '"
        hl.Text = "Daily Report"
        e.Row.Cells(0).Text = ""
        e.Row.Cells(0).Controls.Add(hl)
    End If

End Sub


<asp:GridView ID="gvDaily" runat="server" Height="80px" Width = "180px" CssClass="tableText"    
          OnRowDataBound="gvDaily_RowDataBound">
          <RowStyle HorizontalAlign="center" />                
</asp:GridView>
+2  A: 

Try this new page load. With a "FileDate" column.

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Dim dt As New Data.DataTable()
        dt.Columns.Add("Daily Reports", Type.[GetType]("System.String"))
        dt.Columns.Add("FileDate", GetType(System.DateTime))

        For Each name As [String] In System.IO.Directory.GetFiles(Server.MapPath("~\reports\pdf\"))

            Dim fi As New System.IO.FileInfo(name)

            dt.Rows.Add(New Object() {name, fi.LastWriteTime})
        Next

        Dim dv As DataView = dt.DefaultView
        dv.Sort = dt.Columns("FileDate").ColumnName & " " & "desc"
        dt = dv.ToTable

        Me.gvDaily.DataSource = dt
        Me.gvDaily.DataBind()

    End If
End Sub

To show just the column you want, use this as your Gridview.

<asp:GridView ID="gvDaily" runat="server" Height="80px" Width = "180px" CssClass="tableText"    
          OnRowDataBound="gvDaily_RowDataBound" AutoGenerateColumns="false">
          <RowStyle HorizontalAlign="center" />
    <Columns>
        <asp:BoundField DataField="Daily Reports" HeaderText="Daily Report" />
    </Columns>               
</asp:GridView>
Carter
I was hoping to avoid adding another column for date, because the date is already included in the filename, which the user clicks on to open the file. Worst case, this'll do though. Thanks!
Albert
@Albert You can include another column as part of the data source without displaying it. Just use BoundFields and turn off AutoGenerateColumns on the Grid.
Josh Stodola
@Albert If you don't want to see the column you should create a <asp:BoundField DataField="Daily Reports" /> and set AutoGenerateColumns="false" in the gridview. (See edit).
Carter
A: 

Only for the sake of completeness - i would recommend to use a Datatable/Dataview with an (in)visible date-column like Carters answer. But you can also use a Collection as Datasource for your Grid with Custom objects and Comparer. I have created a small sample to make it clear what i mean:

Partial Public Class WebForm1
    Inherits System.Web.UI.Page

    Private Sub WebForm1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            BindData()
        End If
    End Sub

    Private Sub BindData()
        Dim usCulture As New Imports System.GlobalizationCultureInfo("en-US")
        System.Threading.Thread.CurrentThread.CurrentCulture = usCulture
        Dim nextDate As Date = New Date(2010, 1, 15)
        Dim files As New List(Of FileDate)
        Dim rnd As New Random(Date.Now.Millisecond)
        For i As Int32 = 1 To 100
            Dim fileName As String = "DailySalesReport" & i
            files.Add(New FileDate(fileName, nextDate))
            nextDate = nextDate.AddDays(rnd.Next(-10, 10))
        Next
        files.Sort(New FileComparer(SortDirection.Descending))
        Me.GridView1.DataSource = files
        Me.GridView1.DataBind()
    End Sub
End Class

Class FileDate
    Public FileName As String
    Public FileDate As Date

    Public Sub New(ByVal FileName As String, ByVal FileDate As Date)
        Me.FileName = FileName
        Me.FileDate = FileDate
    End Sub

    Public ReadOnly Property Text() As String
        Get
            Return Me.ToString
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return FileName & "-" & FileDate.ToShortDateString
    End Function
End Class

Class FileComparer
    Implements IComparer(Of FileDate)

    Public Direction As SortDirection

    Public Sub New(ByVal direction As SortDirection)
        Me.Direction = direction
    End Sub

    Public Function Compare(ByVal x As FileDate, ByVal y As FileDate) As Integer Implements System.Collections.Generic.IComparer(Of FileDate).Compare
        If x Is Nothing Then
            If y Is Nothing Then
                Return 0
            Else
                Return -1
            End If
        Else
            If y Is Nothing Then
                Return 1
            Else
                If Me.Direction = SortDirection.Ascending Then
                    Return x.FileDate.CompareTo(y.FileDate)
                Else
                    Return y.FileDate.CompareTo(x.FileDate)
                End If
            End If
        End If
    End Function
End Class

In this sample only the Text property(filename and date) of FileDate will shown as column in the Grid because its the only public property in FileDate. The aspx-Page contains only an empty GridView.

Tim Schmelter