Showing posts with label repeater. Show all posts
Showing posts with label repeater. Show all posts

Aug 28, 2009

ASP.Net Custom Paging Control

I've been playing with GridViews for quite some time & have always wondered if there's a better way of displaying the pager at the bottom, instead of the "1 2 3 ..." that you get by default.

As it worked out, I had the reason today to look more into this for a customer request. I happened to find an article that gave code to do this. It was a decent starting point, but I didn’t like how the records displayed were numbered from 0-(count-1), but it got me going.

Here’s what two options I’m considering using:

This one uses media player type links (i.e. |< << >> >|)
<PagerTemplate>
<asp:LinkButton CommandName="Page" CommandArgument="First" ID="LinkButton1" runat="server" Style="color: white">|&lt;</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="LinkButton2" runat="server" Style="color: white">&lt;&lt;</asp:LinkButton>
[Records <%= (Grid.PageIndex * Grid.PageSize)+1 %> - <%= Grid.PageIndex * Grid.PageSize + Grid.Rows.Count %> (<%= iTotalRecordCount %>)]
<asp:LinkButton CommandName="Page" CommandArgument="Next" ID="LinkButton3" runat="server" Style="color: white">&gt;&gt;</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Last" ID="LinkButton4" runat="server" Style="color: white">&gt;|</asp:LinkButton>
</PagerTemplate>
And this one has words for First/Last as well:
<PagerTemplate>
<asp:LinkButton CommandName="Page" CommandArgument="First" ID="LinkButton1" runat="server" Style="color: white">&lt;&lt; First</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="LinkButton2" runat="server" Style="color: white">&lt; Prev</asp:LinkButton>
[Records <%= (Grid.PageIndex * Grid.PageSize)+1 %> - <%= Grid.PageIndex * Grid.PageSize + Grid.Rows.Count %> (<%= iTotalRecordCount %>)]
<asp:LinkButton CommandName="Page" CommandArgument="Next" ID="LinkButton3" runat="server" Style="color: white">Next &gt;</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Last" ID="LinkButton4" runat="server" Style="color: white">Last &gt;&gt;</asp:LinkButton>
</PagerTemplate>
One caveat, I use a variable iTotalRecordCount that is defined on the code behind:
public int iTotalRecordCount = 0;
And defined in a BindGrid() method I call on button click:
iTotalRecordCount = dataTable.Rows.Count;
Lastly, you need to implement the "OnPageIndexChanging" event:
    protected void Grid_PageIndexChanging( object sender, GridViewPageEventArgs e ) {
Grid.PageIndex = e.NewPageIndex;
BindGrid( );
}
Anyway, I hope someone out there finds this useful. :)

Apr 3, 2009

Nesting a Repeater inside of a GridView that is bound to an Array of Custom Objects

Wow, isn't that title a mouthful! But that's exactly the situation that presented itself to me at work this week. Since it too me way longer than I thought it should to figure out, I figured I'd put my effort in here, just in case it might be able to help someone else out someday (possibly even me).

Here's the results:
#NameEmail Addresses
1Ian CazabatIanCazabat@Example.com
Ian.B.Cazabat@Example.com
IanCaz@Example.com
2Malcolm ReynoldsCptnMal@Example.com
Serenity1@Example.com
3Jonas BlaneSnakeDr@Example.com
303rdLSG@Example.com


So, without any further delay here's the code:
ASPX:
<%@ Page Language="c-sharp" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Nested Sample</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvNestingSample" AutoGenerateColumns="False" runat="server" BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Vertical">
<RowStyle VerticalAlign="Top" BackColor="#EEEEEE" ForeColor="Black" />
<Columns>
<asp:BoundField DataField="EmployeeId" HeaderText="#" />
<asp:BoundField DataField="EmployeeName" HeaderText="Name" />
<asp:TemplateField HeaderText="Email Addresses">
<ItemTemplate>
<asp:Repeater runat="server" ID="rptEmailAddrs" DataSource='<%# DataBinder.Eval( Container.DataItem, "EmailAddresses" ) %>'>
<ItemTemplate>
<a href="mailto:<%# Container.DataItem %>"><%# Container.DataItem %></a><br />
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="#DCDCDC" />
</asp:GridView>
</div>
</form>
</body>
</html>


CodeBehind:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page {
protected void Page_Load( object sender, EventArgs e ) {
UserAccount[ ] aryUserAccounts = new UserAccount[ ] {
new UserAccount( 1, "Ian Cazabat", new string[] {"IanCazabat@Example.com", "Ian.B.Cazabat@Example.com", "IanCaz@Example.com"}),
new UserAccount( 2, "Malcolm Reynolds", new string[] {"CptnMal@Example.com", "Serenity1@Example.com"}),
new UserAccount( 3, "Jonas Blane", new string[] {"SnakeDr@Example.com", "303rdLSG@Example.com"})
};

gvNestingSample.DataSource = aryUserAccounts;
gvNestingSample.DataBind( );
}

public class UserAccount {
private long employeeid;
private string employeename;
private string[ ] emailaddresses;

public long EmployeeId {
get { return employeeid; }
set { employeeid = value; }
}
public string EmployeeName {
get { return employeename; }
set { employeename = value; }
}
public string[ ] EmailAddresses {
get { return emailaddresses; }
set { emailaddresses = value; }
}

public UserAccount( ) {
}

public UserAccount( long lEmployeeId, string strEmployeeName, string[] aryEmails ) {
this.employeeid = lEmployeeId;
this.employeename = strEmployeeName;
this.emailaddresses = aryEmails;
}
}
}

Okay, so there you have a working sample of how to create a GridView with a nested Repeater, that gets it's data from an Array of Custom Objects. Here's a couple points of interest:
  1. In order to bind on the data in the object, they must be created as "fields" using get/set.
  2. To access the array that's part of the object use:
    DataSource='<%# DataBinder.Eval( Container.DataItem, "{Array Property Name}" ) %>'
  3. To display the "data elements" from the array, you use:
    <%# Container.DataItem %>
  4. If the "data elements" in the array are custom objects, then you need to use the following:
    <%# DataBinder.Eval( Container.DataItem, "{Property of Custom Object from Array}" )%>
Okay, so that's about got it, hopefully I've helped someone out & I've likely kept myself from losing too much sleep over this issue again! So, go forth & create! ;)