I have a TextBox in a repeater that is populated from the database in the ItemDataBound event. When I tried to get the text inside the TextBox in a Button_Click event I found the TextBox.Text empty. How can I get the Text?
foreach (RepeaterItem repeated in repEdit.Items)
{
DropDownList drp = (DropDownList)FindControlRecursive(repeated, "drpdown");
TextBox txt = (TextBox)FindControlRecursive(repeated, "txt");
CheckBox chk = (CheckBox)FindControlRecursive(repeated, "chk");
if (drp != null && !string.IsNullOrEmpty(drp.Attributes["ID"]))
{
loc.GetType().GetProperty(drp.Attributes["ID"].Split('#')[0] + "ID").SetValue(loc, int.Parse(drp.SelectedValue), null);
}
if (txt != null && !string.IsNullOrEmpty(txt.Attributes["ID"]))
{
if (txt.Attributes["ID"].Contains("#int"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, int.Parse(txt.Text), null);
}
else if (txt.Attributes["ID"].Contains("#decimal"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, decimal.Parse(txt.Text), null);
}
else
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, txt.Text, null);
}
}
if (chk!=null && !string.IsNullOrEmpty(chk.Attributes["ID"]))
{
loc.GetType().GetProperty(chk.Attributes["ID"].Split('#')[0]).SetValue(loc, chk.Checked, null);
}
}
HTML
<asp:Repeater ID="repEdit" runat="server" OnItemDataBound="repEdit_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Visible="false"></asp:Label>
<asp:TextBox ID="txt" runat="server" Visible="false"></asp:TextBox>
<asp:CheckBox ID="chk" runat="server" Visible="false" />
<asp:DropDownList ID="drpdown" runat="server" Visible="false">
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
Here is the itemdatabound event
protected void repEdit_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Label name = e.Item.FindControl("lblName") as Label;
TextBox text = e.Item.FindControl("txt") as TextBox;
CheckBox chk = e.Item.FindControl("chk") as CheckBox;
DropDownList drp = e.Item.FindControl("drpdown") as DropDownList;
Button but = e.Item.FindControl("butEdit") as Button;
//butEdit.Visible = true;
if (but != null)
{
but.Visible = true;
}
if (e.Item.ItemType == ListItemType.Item)
{
KeyValuePair<string, Dictionary<int, string>> kvp = (KeyValuePair<string, Dictionary<int, string>>)e.Item.DataItem;
if (name != null)
{
if (kvp.Key.Contains("#datetime"))
{
return;
}
name.Visible = true;
name.Text = kvp.Key.Split('#')[0].ToString();
}
if (kvp.Key.Contains("#int") || kvp.Key.Contains("#decimal"))
{
text.Visible = true;
text.ID = kvp.Key;
text.EnableViewState = true;
text.Attributes["ID"] = kvp.Key;
text.Text = kvp.Value[0].ToString();
if (kvp.Key.Split('#')[0] == "ID")
{
text.Enabled = false;
}
}
Here is your Repeater. It has a PlaceHolder and Button.
<asp:Repeater ID="rpNotifications" runat="server"
OnItemDataBound="rpNotifications_ItemDataBound">
<ItemTemplate>
<asp:PlaceHolder ID="commentHolder" runat="server"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnComment"
Text="Comment" CssClass="btn blue"
OnClick="btnComment_Click" CommandArgument='<%# Eval("id") %>' />
</ItemTemplate>
</asp:Repeater>
The button has the command argument set as the Id of the data I am binding to it.
Next here is where you need to Bind your Repeater. If you don't Bind it in the Page_Init the resulting values in the dynamically created controls will be lost.
protected void Page_Init(object sender, EventArgs e)
{
rpNotifications.DataSource = {datasource-here}
rpNotifications.DataBind();
}
And here is why (Image from: http://msdn.microsoft.com/en-us/library/ms972976.aspx)
Dynamically Create Control on ItemDataBound You will need to add the textbox to the placeholder as this is the only way to dynamically assign an ID to the control.
protected void rpNotifications_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem)
{
Common.Models.Item item = (Common.Models.Item)e.Item.DataItem;
// Create new Control
TextBox txtComment = new TextBox();
txtComment.ID = String.Format("txtComment{0}", item.id.ToString());
// Ensure static so you can reference it by Id
txtComment.ClientIDMode = System.Web.UI.ClientIDMode.Static;
// Add control to placeholder
e.Item.FindControl("commentHolder").Controls.Add(txtComment);
}
}
Get Value On Button Click Now you need to create the event handler for the button and get the resulting value
protected void btnComment_Click(object sender, EventArgs e)
{
// This is the ID I put in the CommandArgument
Guid id = new Guid(((Button)sender).CommandArgument);
String comment = String.Empty;
// Loop through the repeaterItems to find your control
foreach (RepeaterItem item in rpNotifications.Controls)
{
Control ctl = item.FindControl(
String.Format("txtComment{0}", id.ToString()));
if (ctl != null)
{
comment = ((TextBox)ctl).Text;
break;
}
}
}