I need to sort my records by date (month & year) as displayed on my asp.net page;
Any ideas / suggestions would be helpful.
This is the code I currently ha
You can do this with a Repeater. Something like this (you should be able to adapt it easily):
<asp:Repeater ID="rpt" runat="server" OnItemDataBound="rpt_RowDataBound">
<ItemTemplate>
<table runat="server" style="color: White; background-color: #3A4F63;" visible="false"
id="headerTable">
<tr>
<td colspan="3">
<asp:Label ID="headerTitle" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td style="width: 200px; background-color: #3A4F63; color: White;">
Name
</td>
<td style="width: 200px;">
Directory Name
</td>
<td style="width: 200px;">
Creation Time
</td>
</tr>
</table>
<!-- These are the actual data items -->
<!-- Bind to your specific properties i.e. Invoice #, file type, etc. -->
<table>
<tr>
<td style="width: 200px;">
<asp:Label ID="lblName" runat="server" Text='<%#Eval("Name") %>'></asp:Label>
</td>
<td style="width: 200px;">
<asp:Label ID="lblDirName" runat="server" Text='<%#Eval("DirectoryName") %>'></asp:Label>
</td>
<td style="width: 200px;">
<asp:Label ID="lblCreationTime" runat="server" Text='<%#Eval("CreationTime") %>'></asp:Label>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
On Code Behind, the OnItemDataBound looks like this:
Private month As Integer = -1
Private year As Integer = -1
Protected Sub rpt_RowDataBound(sender As Object, e As RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
'Binding to FileInfo objects. You are binding to DataTable. Adjust it accordingly
If month <> TryCast(e.Item.DataItem, FileInfo).CreationTime.Month OrElse year <> TryCast(e.Item.DataItem, FileInfo).CreationTime.Year Then
month = TryCast(e.Item.DataItem, FileInfo).CreationTime.Month
year = TryCast(e.Item.DataItem, FileInfo).CreationTime.Year
e.Item.FindControl("headerTable").Visible = True
TryCast(e.Item.FindControl("headerTitle"), Label).Text = "Files for " & TryCast(e.Item.DataItem, FileInfo).CreationTime.ToShortDateString()
Else
e.Item.FindControl("headerTable").Visible = False
End If
End If
End Sub
The way I bound my data to the repeater is like this:
Dim fi As FileInfo() = New DirectoryInfo("C:\").GetFiles().OrderByDescending(Function(x) x.CreationTime).ToArray()
rpt.DataSource = fi
rpt.DataBind()
Produces this output:

The ASP.NET content that you have should be put in a Repeater. The files that you have should then be grouped by the month and date. So basically you will end up with a parent-child list. The parent which is the group of files will be bound to the Repeater, and the children which are the files belonging to that group will be bound the the GridView in the Repeater.
The ASP.NET content would be something along this line. Take note the gvInvoiceList DataSource property is bound to InvoiceList, a property of the group that I came up with (which you will see in the code below) that will have a list of files belonging to the group.
<asp:Repeater ID="repInvoiceGroups" runat="server">
<ItemTemplate>
<table width="40%" border="0" style="margin-left:auto; margin-right:auto;">
<tr><td><asp:Label ID="lblGridHeader" CssClass="TextFont"
Text='<%# Eval("MonthYear", "{0:MMMM yyyy}") %>'
runat="server"></asp:Label></td></tr>
<tr>
<td align="center">
<asp:GridView ID="gvInvoiceList" runat="server"
AutoGenerateColumns="false" AllowSorting="true"
DataSource='<%# Eval("InvoiceList") %>'>
<columns>
<asp:TemplateField ItemStyle-Width="10%" HeaderText="File Type">
<ItemTemplate><asp:HyperLink ID="imgFileType" ImageUrl="images/Icon_Pdf.gif" NavigateUrl='<%# SetNavigateUrl(Eval("Name")) %>' runat="server"></asp:HyperLink></ItemTemplate>
</asp:TemplateField>
<asp:boundfield datafield="Name" headertext="Invoice #"/>
<asp:boundfield datafield="LastWriteTime" headertext="Date Modified"/>
</columns>
</asp:GridView>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
As for the code, I'm not fluent on using DataTable to have the parent-child relationship needed for the ASP.NET structure that I used for my answer, but it should be easily doable using normal classes. And I'm also not fluent on using VB.NET, so excuse my example which will be using C#, which I guess you should able to convert it quite easily to VB.NET.
I'm using Linq to do the grouping and an anonymous class to have the parent-child relationship for this, so the code is rather short.
repInvoiceGroups.DataSource = files
.GroupBy(f => f.LastWriteTime.ToString("yyyy-MM"))
.Select(g => new {
MonthYear = DateTime.ParseExact(g.Key, "yyyy-MM", CultureInfo.InvariantCulture),
InvoiceList = g.OrderByDescending(f => f.LastWriteTime) })
.OrderByDescending(o => o.MonthYear);
repInvoiceGroups.DataBind();
p/s: The code was written in a text editor and untested. Let me know if you face any errors. :)