0

I have a gridview and one of the bound fields contains a date (CureExpires), I am looking to have this date replaced with the word "Expired" if the date is older than the current date and time. How would I accomplish this?

Example of how it would look: enter image description here

My Code:

<asp:GridView runat="server" ID="PendingList" CssClass="wiretable" AutoGenerateColumns="False"
     AllowPaging="True" BorderColor="#E8CC6B" BorderStyle="Solid" BorderWidth="1px"
     Width="100%" OnPageIndexChanging="PendingList_PageIndexChanging" PageSize="10"
     ShowFooter="True" OnRowDataBound="PendingList_RowDataBound">
     <Columns>
       <asp:BoundField DataField="MemberName" HeaderText="Member Name" />
       <asp:BoundField DataField="Owes" HeaderText="Owes" />
       <asp:BoundField DataField="Paid" HeaderText="Paid" />
       <asp:BoundField DataField="CureExpires" DataFormatString="{0:MM/dd/yy}"
                        HeaderText="Expires" />
       <asp:HyperLinkField DataNavigateUrlFields="ID" DataNavigateUrlFormatString="Payment.aspx?ID={0}"
                        Text="Record Payment" HeaderText="" />
      </Columns>
</asp:GridView>

Update: More code

  public partial class Branch : System.Web.UI.Page
{
    public class Member
    {
        public int ID { get; set; }
        public string MemberName { get; set; }
        public int Owes { get; set; }
        public int Paid { get; set; }
        public DateTime? CureExpires { get; set; }
    }
 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            bindGridView();
    }
  public void bindGridView()
    {
        var id = Request.Params["ID"];
        string connStr = "";
        SqlConnection mySQLconnection = new SqlConnection(connStr);
        if (mySQLconnection.State == ConnectionState.Closed)
        {
            mySQLconnection.Open();
        }
        SqlCommand mySqlCommand = new SqlCommand(@"SELECT
                                   C.ID, C.MemberName, C.CureExpires,
                               C.CureAmt - COALESCE(SUM(P.PaymentAmt),0) as Owes,
                               COALESCE (SUM(P.PaymentAmt),0) as Paid,
                               C.CureAmt
                            FROM
                               Cure C
                               LEFT JOIN CurePayment P
                               ON C.ID = P.CureID
                            WHERE
                           C.Status = '2' and C.TransWorldAcct = '0'
                           and C.Branch = " + "'" + id + "'" + " GROUP BY C.MemberName, C.CureExpires, C.CureAmt, C.ID", mySQLconnection);

        SqlDataAdapter mySqlAdapter = new SqlDataAdapter(mySqlCommand);
        DataSet myDataSet = new DataSet();
        mySqlAdapter.Fill(myDataSet);
        PendingList.DataSource = myDataSet;
        PendingList.DataBind();
        if (mySQLconnection.State == ConnectionState.Open)
        {
            mySQLconnection.Close();
        }
     }
    protected void PendingList_RowDataBound(object sender,
                                                GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Cells[2].ForeColor = System.Drawing.Color.Green;
            e.Row.Cells[1].ForeColor = System.Drawing.Color.Red;

            var expiresLiteral = e.Row.FindControl("ExpiresLiteral") as Literal;
            var member = e.Row.DataItem as Member;

            if (!member.CureExpires.HasValue)
                expiresLiteral.Text = "N/A";
            else if (member.CureExpires.Value < DateTime.Now)
                expiresLiteral.Text = "Expired";
            else
                expiresLiteral.Text = member.CureExpires.Value.ToShortDateString();
           }
techora
  • 619
  • 3
  • 18
  • 38
  • Going to be kind of tricky since you are forcing a `DateTime` format on the column in question. You would need to override both the custom formatting AND the column type (if it is of type `DateTime`). – Evan L May 24 '13 at 14:06
  • Yeah it's being pulled in from a SQL database as DateTime. Hmm I'm trying to think if there a way to remove the forced DateTime format and format it from the code behind page (aspx.cs). – techora May 24 '13 at 14:10
  • You could convert the entire column to `String`, make it look like date time using your format and then the Expired condition will work. BUT if you are updating any changes back to the database you will need to convert the column values back to type `DateTime` – Evan L May 24 '13 at 14:13

1 Answers1

4

You are almost there. You just need to add the logic inside PendingList_RowDataBound.

enter image description here

public class Member
{
    public int ID { get; set; }
    public string MemberName { get; set; }
    public int Owes { get; set; }
    public int Paid { get; set; }
    public DateTime? CureExpires { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        PendingList.DataSource = new List<Member>
            {
                new Member {ID = 1, MemberName = "John", Owes = 10, 
                    Paid = 5, CureExpires = new DateTime(2013, 5, 25)},
                new Member {ID = 2, MemberName = "Sam", Owes = 100, 
                    Paid = 50, CureExpires = new DateTime(2013, 5, 23)},
                new Member {ID = 3, MemberName = "Mark", Owes = 12, 
                    Paid = 2, CureExpires = new DateTime(2013, 6, 1)},
                new Member {ID = 3, MemberName = "Lisa", Owes = 40, 
                    Paid = 35, CureExpires = null},
            };
        PendingList.DataBind();
    }
}

protected void PendingList_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var expiresLiteral = e.Row.FindControl("ExpiresLiteral") as Literal;
        var member = e.Row.DataItem as Member;

        if (!member.CureExpires.HasValue)
            expiresLiteral.Text = "N/A";
        else if (member.CureExpires.Value < DateTime.Now)
            expiresLiteral.Text = "Expired";
        else
            expiresLiteral.Text = member.CureExpires.Value.ToShortDateString();
    }
}

<asp:GridView runat="server" ID="PendingList" AutoGenerateColumns="False" 
  OnRowDataBound="PendingList_RowDataBound">
    <Columns>
        <asp:BoundField DataField="MemberName" HeaderText="Member Name" />
        <asp:BoundField DataField="Owes" HeaderText="Owes" />
        <asp:BoundField DataField="Paid" HeaderText="Paid" />
        <asp:TemplateField HeaderText="Expires">
            <ItemTemplate>
                <asp:Literal runat="server" ID="ExpiresLiteral" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:HyperLinkField DataNavigateUrlFields="ID"   
             DataNavigateUrlFormatString="Payment.aspx?ID={0}"
            Text="Record Payment" HeaderText="" />
    </Columns>
</asp:GridView>

Updated for DataSet DataSource

protected void PendingList_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DateTime cureExpires;
        var expiresLiteral = e.Row.FindControl("ExpiresLiteral") as Literal;
        var obj = ((DataRowView) e.Row.DataItem)["CureExpires"];

        if (obj != null && DateTime.TryParse(obj.ToString(), out cureExpires))
        {
            if (cureExpires < DateTime.Now)
                expiresLiteral.Text = "Expired";
            else
                expiresLiteral.Text = cureExpires.ToShortDateString();
        }
        else
        {
            expiresLiteral.Text = "N/A";
        }
    }
}
Win
  • 61,100
  • 13
  • 102
  • 181
  • This is a great help Win, thank you very much. I only have one question, say one of the CureExpires values is NULL, how can I handle that? – techora May 24 '13 at 14:40
  • I updated the answer and screen shot. It checks to make sure CureExpires is not null. – Win May 24 '13 at 14:45
  • That code works great by itself but when I merge it within mine properly I'm getting "Object reference not set to an instance of an object." on the "if (!member.CureExpires.HasValue)" line. When I debug it tells me member is null. I am updating my initial post with my database code as well, one moment. – techora May 24 '13 at 16:07
  • Oop! Your datasource is `DataSet`. I updated the answer with code which casts `DataItem` to `DataRowView`. – Win May 24 '13 at 16:40