It's been a while since I've used the data controls in asp.net, so here goes.
My tsql query returns this datatable:
State City First Last
----------------------------------------------------------
Florida Miami Bob Jones
Florida Miami Joe James
Florida Miami Mary Hart
Florida Miami Jane Smith
Florida Orlando Tina Karl
Florida Orlando George Williams
Florida Orlando Ralph Davis
I want some simple data control that will display the data like so, without much hassle. I simply don't want to repeat the state/city for every row:
Florida Miami
Bob Jones
Joe James
Mary Hart
Jane Smith
Florida Orlando
Tina Karl
George Williams
Ralph Davis
I recommend you use a listview.
You can do it like this:
First, use the wizard to lay out the listview (create it for you).
Delete all the templates - only leave in the item template.
So this is what the result is:
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<tr style="">
<td><asp:Label ID="ProvinceLabel" runat="server" Text='<%# Eval("Province") %>' /></td>
<td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
<td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table runat="server">
<tr runat="server">
<td runat="server">
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server">Province</th>
<th runat="server">City</th>
<th runat="server">HotelName</th>
<th runat="server">FirstName</th>
<th runat="server">LastName</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
And the output looks like this:
The code to load up the grid? So far we have this:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
loadGrid();
}
public void loadGrid()
{
string strSQL;
strSQL = "SELECT Province, City, HotelName, FirstName, LastName from tblHotels ORDER BY Province, City";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
ListView1.DataSource = cmdSQL.ExecuteReader;
ListView1.DataBind();
}
}
Ok, so we assume that the first two columns ARE ordered correctly as per above.
but, now lets add a grouping to the above.
Our item template thus becomes this:
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<tr id="MyGroupHeading" runat="server" style="display:normal">
<td><asp:Label ID="Province" runat="server" Text='<%# Eval("Province") %>' /></td>
<td><asp:Label ID="City" runat="server" Text='<%# Eval("City") %>' /></td>
</tr>
<tr>
<td colspan="2"></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
<td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
</tr>
</ItemTemplate>
So, note how we just added a "tr" (table row)
Now, we can hide/show this extra header like this:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
ListViewDataItem LvRow = e.Item;
if (LvRow.ItemType == ListViewItemType.DataItem)
{
var strNewGroup = (Label)LvRow.FindControl("Province").Text;
strNewGroup += "*" + (Label)LvRow.FindControl("City").Text;
HtmlTableRow MyTr = (HtmlTableRow)LvRow.FindControl("MyGroupHeading");
if (strNewGroup != strMyGroup)
{
// a new group -
strMyGroup = strNewGroup;
MyTr.Style("display") = "normal";
}
else
MyTr.Style("display") = "none";
}
}
So we really just manual code though this. The results now look like this;
And formatting? Well, if I drop my default css table format, then I get/see this:
And I suppose, if we wanted, we could pull left the sub group.
<tr>
<td colspan="2"></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
<td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
</tr>
Change the above col span from 2 to 1, or even remove the col span.