Get TextBox values from a Repeater the easy way (ASP.NET C#)

The asp:Repeater control allows you to attach an ItemCommand event to it, for instance, updating a record in a database.

<asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server" 
 OnItemCommand="MyRepeater_ItemCommand">
 <HeaderTemplate><ul></HeaderTemplate>
 <ItemTemplate><li>
 Url: <asp:TextBox ID="Urdl" Text='<%# Eval("Url") %>' runat="server" />
 Text: <asp:TextBox ID="Text" Text='<%# Eval("Text") %>' runat="server" />
 <asp:Button ID="SaveButton" CommandName="Save" CommandArgument='<%# Eval("RecordID") %>' Text="Save" runat="server" />
 </li></ItemTemplate>
 <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

MyRepeater_ItemCommand is then defined:

protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
 switch (e.CommandName.ToString())
 {
  case "Save":
   int recordID = Convert.ToInt32(e.CommandArgument);
   TextBox url = e.Item.FindControl("Url") as TextBox;
   TextBox text = e.Item.FindControl("Text") as TextBox;
   
   ....
   
   break;
  default:
   break;
 }
}

However this has several downsides:

  1. If you mistype the control id, you get a NullReferenceException
  2. The code can get cluttered and harder to understand as more TextBox's are added.

To help mitigate this, this function gets the value of the TextBox, or null if the TextBox is not found.

public string TextBoxValue(RepeaterItem itm, string controlId)
{
 string output = null;
 TextBox t = itm.FindControl(controlId) as TextBox;
 if (t != null)
 {
  output = t.Text;
 }
 return output;
}

Then you can get the value without an exception occurring:

string url = TextBoxValue(e.Item, "Url");
string text = TextBoxValue(e.Item, "Text");
if(url != null)
{
    // update url in record
}
if(text == null)
{
    // update text in record
}

The code could then be used in a class and used on multiple pages, so if a page doesn't have a TextBox with a certain ID, the corresponding data field is not updated (e.g. on one page you might want a user to update the URL, but on another more restricted page, you may only want them to change the text). Code behind would then just be:

protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
 RepeaterMethods.MyRepeater_ItemCommand(sender, e);
}

And the class could be:

using System;
using System.Collections.Generic;
using System.Web;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

/// <summary>
/// Summary description for RepeaterMethods
/// </summary>
public class RepeaterMethods
{
 public RepeaterMethods()
 {
  //
  // TODO: Add constructor logic here
  //
 }

 public static void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
 {
  switch (e.CommandName.ToString())
  {
   case "Save":
    string url = TextBoxValue(e.Item, "Url");
    string text = TextBoxValue(e.Item, "Text");
    if (url != null)
    {
     // update url in record
    }
    if (text == null)
    {
     // update text in record
    }
    break;
   default:
    break;
  }
 }

 public static string TextBoxValue(RepeaterItem itm, string controlId)
 {
  string output = null;
  TextBox t = itm.FindControl(controlId) as TextBox;
  if (t != null)
  {
   output = t.Text;
  }
  return output;
 }
}

Comments

DjarDjar said…
GREAT SOLUTION! really helped me with my project. Always avoided the repeater control when textboxes were involved. I was looking for months for a solution like this!

Popular posts from this blog

Link: HTML Agility Pack (.NET)

Basic Excel Spreadsheet Generation (ASP/ASP.NET)

ASP.NET: Binding alphabet to dropdown list