2

In my <asp:Repeater></asp:Repeater> - There is one hidden field, textbox and button.

When data will be bound, then hidden filed will get User Id like below code

<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>

and ItemDataBound event will be called and in this function, i am getting value from hidden field and concatenating that value as a Id in text box. like below code

            TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
            HiddenField hf = (HiddenField)e.Item.FindControl("hide");//1
            txt.ID = "txtReplyArea" + hf.Value;//txtReplyArea1

Suppose only one record comes from database and their UserId is 1. Then textbox Id should be "textReplyArea1". From now, all are correct.

I am not sure, it's correct way to giving dynamic Id to repeater control but i think, it's correct.

Problem -

When i click on button and i get a items from repeater and textbox from Id by finding control from repeater then it shows null.

        int areaId = int.Parse((sender as Button).CommandArgument);//1
        string id="txtReplyArea"+areaId;//txtReplyArea1

        foreach (RepeaterItem item in repeaterBlog.Items)
        {
            TextBox tb = item.FindControl(id) as TextBox;//tb = null
        }

Code of aspx page

<%@ Page Title="Messages" Language="C#" MasterPageFile="~/Menu.master" AutoEventWireup="true" CodeFile="Messages.aspx.cs" Inherits="Messages" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <div style="width:70%;">
        <asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
        <HeaderTemplate>
            <table>
            </HeaderTemplate>
                <ItemTemplate>
                    <tr >
                        <td>
                            <asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
                            <asp:TextBox  ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
                        </td>
                    </tr>
                    <tr>
                        <td style="margin-left:47%;">
                            <asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True" CommandArgument='<%#Eval("UserId")%>'/>
                        </td>
                    </tr>

                </ItemTemplate>
                <FooterTemplate>
            </table>
                </FooterTemplate>
        </asp:Repeater>

    </div>
</asp:Content>

Code of aspx.cs

            SqlCommand cmd;
            SqlDataReader sdr;
           protected void Page_Load(object sender, EventArgs e)
           {
              if(!IsPostBack)
              { 
    String cs = ConfigurationManager.ConnectionStrings["myWebsite"].ConnectionString;
    using (SqlConnection con = new SqlConnection(cs))
        {

            cmd = new SqlCommand("select * from ContactMessage", con);
            con.Open();
            sdr = cmd.ExecuteReader();

            repeaterBlog.DataSource = sdr;
            repeaterBlog.DataBind();
            con.Close();
        }
    }

}

public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
        HiddenField hf = (HiddenField)e.Item.FindControl("hide");
        txt.ID = "txtReplyArea" + hf.Value;
    }
}


protected void btnReplyClicked(object sender, EventArgs e)
{
    int areaId = int.Parse((sender as Button).CommandArgument);
    string id="txtReplyArea"+areaId;

    foreach (RepeaterItem item in repeaterBlog.Items)
    {
        TextBox tb = item.FindControl(id) as TextBox;
    }

}

}
Puneet Chawla
  • 5,729
  • 4
  • 16
  • 33

2 Answers2

2

This worked for me. Notice that I removed EnableViewState from the repeater and added OnItemDatabound event.

<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
    <HeaderTemplate>
        <table>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td>
                <asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server" />
                <asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8"
                    Visible="false"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td style="margin-left: 47%;">
                <asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True"
                    CommandArgument='<%#Eval("UserId")%>' />
            </td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

    protected void Page_Load(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("UserId");
        DataRow dr = dt.NewRow();
        dr[0] = 34;
        dt.Rows.Add(dr);
        repeaterBlog.DataSource = dt;
        repeaterBlog.DataBind();
    }

    public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
            HiddenField hf = (HiddenField)e.Item.FindControl("hide");
            txt.ID = "txtReplyArea" + hf.Value;
        }
    }


    protected void btnReplyClicked(object sender, EventArgs e)
    {
        int areaId = int.Parse((sender as Button).CommandArgument);
        string id = "txtReplyArea" + areaId;

        foreach (RepeaterItem item in repeaterBlog.Items)
        {
            TextBox tb = item.FindControl(id) as TextBox;
        }
    }
thewisegod
  • 1,524
  • 1
  • 10
  • 11
  • When i use your code then error comes on run application - The ID property of a control can only be set using the ID attribute in the tag and a simple value. Example: . That's why i tried to get id by hidden field. – Puneet Chawla Aug 22 '15 at 03:27
  • I removed EnableViewState from the repeater and added OnItemDatabound event. But still it doesn't solve. i am not saying your code is wrong,, but in my code it doesn't work. – Puneet Chawla Aug 22 '15 at 03:59
  • Did you verify that it's hitting all codebehind events? – thewisegod Aug 22 '15 at 04:02
  • Make sure that you are not binding your repeater inside a check for postback. If you code is inside a !IsPostBack, tb will = null. – thewisegod Aug 22 '15 at 04:11
  • Yes, all codebehind event is being fired. But i am binding my repeater inside a check for postback. If i remove it then it shows another error when i click on button "Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. " – Puneet Chawla Aug 22 '15 at 04:14
  • Problem solved only in one way. If i remove postback condtion from pageload function and use EnableEventValidation="false" in aspx page. But when i click on button then pageload code again executed because i removed postback condition.. But textboxId shows correct. – Puneet Chawla Aug 22 '15 at 04:18
  • 1
    Yes, the reason this is happening is because you are setting the ID dynamically and unless you call bind each time, that control will not exist on the page anymore. For this, please mark as answered. – thewisegod Aug 22 '15 at 04:24
  • But I think its wrong when any event will be fired then page load function code will be executed but it should not be. Don't worry I will accept answer because u solved it almost. Let me complete this properly – Puneet Chawla Aug 22 '15 at 04:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87642/discussion-between-puneet-chawla-and-thewisegod). – Puneet Chawla Aug 22 '15 at 09:25
-2

You can try like this

<asp:TextBox ID='<%# "txtReplyArea" + Convert.ToString(Eval("UserId")%>)' runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
GMD
  • 761
  • 5
  • 21
  • Thanks for answer. When i use your code this error comes. - '<%# "txtReplyArea" + Convert.ToString(Eval("UserId")%>)' is not a valid identifier. – Puneet Chawla Aug 22 '15 at 09:24
  • 1
    You can't put an Eval in the ID attribute, see this question http://stackoverflow.com/questions/1859206/eval-script-for-server-side-controls-id-property – JJP May 02 '16 at 15:26