Search code examples
.netnestedrepeateritemcommand

.NET nested repeater - Button click calls OnItemCreated eventhandler, not OnItemCommand


I have a project with a simple nested repeater. When i click the button, the OnItemCommand event is not called but the OnItemCreated is called (however, it does not call the Page_Load event handler). What am I misssing?

MARKUP

  <table width="100%">
    <tr>
        <td>my row</td>
        <td>my description</td>
    </tr>
    <asp:Repeater ID="rptMain" runat="server" OnItemCreated="rptMain_ItemCreated" OnItemCommand="rptMain_ItemCommand">
        <ItemTemplate>
        <tr style="background-color:#45abdc;">
            <td><asp:LinkButton ID="ibtnDoSomething" runat="server" CommandArgument="SELECT" Text="Clicky" /></td>
            <td><asp:Label ID="lblMainData" runat="server"></asp:Label></td>

        </tr>
        <asp:Repeater ID="rptChild" runat="server" OnItemCreated="rptChild_ItemCreated">
            <ItemTemplate>
                <tr style="background-color:#bcbbcb;">
                    <td>

                    </td>
                    <td>
                        <asp:Label ID="lblChildData" runat="server"></asp:Label>
                    </td>

                </tr>

            </ItemTemplate>
        </asp:Repeater>
        </ItemTemplate>
    </asp:Repeater>

   </table>

CODEBEHIND DataTable _childdata = new DataTable(); DataTable _data = new DataTable();

        public void Page_Load()
        {

            _data.Columns.Add(new DataColumn("Text"));
            _data.Columns.Add(new DataColumn("CommandValue"));

            DataRow _row1 = _data.NewRow();
            _row1["Text"] = "Butch";
            _row1["CommandValue"] = "31";
            DataRow _row2 = _data.NewRow();
            _row2["Text"] = "Karl";
            _row2["CommandValue"] = "2";
            DataRow _row3 = _data.NewRow();
            _row3["Text"] = "Suzie";
            _row3["CommandValue"] = "8";
            DataRow _row4 = _data.NewRow();
            _row4["Text"] = "Kara";
            _row4["CommandValue"] = "31";

            _data.Rows.Add(_row1);
            _data.Rows.Add(_row2);
            _data.Rows.Add(_row3);
            _data.Rows.Add(_row4);




            _childdata.Columns.Add(new DataColumn("Text"));
            _childdata.Columns.Add(new DataColumn("CommandValue"));

            DataRow _crow1 = _childdata.NewRow();
            _crow1["Text"] = "Butch";
            _crow1["CommandValue"] = "Cupcakes";
            DataRow _crow2 = _childdata.NewRow();
            _crow2["Text"] = "Karl";
            _crow2["CommandValue"] = "Cheese";
            DataRow _crow3 = _childdata.NewRow();
            _crow3["Text"] = "Suzie";
            _crow3["CommandValue"] = "Pizaa";
            DataRow _crow4 = _childdata.NewRow();
            _crow4["Text"] = "Kara";
            _crow4["CommandValue"] = "Tofu";
            DataRow _crow5 = _childdata.NewRow();
            _crow5["Text"] = "Butch";
            _crow5["CommandValue"] = "Bacon";
            DataRow _crow6 = _childdata.NewRow();
            _crow6["Text"] = "Karl";
            _crow6["CommandValue"] = "Ham";

            _childdata.Rows.Add(_crow1);
            _childdata.Rows.Add(_crow2);
            _childdata.Rows.Add(_crow3);
            _childdata.Rows.Add(_crow4);
            _childdata.Rows.Add(_crow5);
            _childdata.Rows.Add(_crow6);

            rptMain.DataSource = _data;
            rptMain.DataBind();

        }

        public void rptMain_ItemCreated(object sender, RepeaterItemEventArgs e)
        {

            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                DataRowView drv = (DataRowView)e.Item.DataItem;

                LinkButton ibtn = e.Item.FindControl("ibtnDoSomething") as LinkButton;
                Label mainLabel = e.Item.FindControl("lblMainData") as Label;
                ibtn.CommandArgument = drv["CommandValue"].ToString();
                mainLabel.Text = drv["Text"].ToString();
                DataView _dv = new DataView(_childdata, "Text = '" + drv["Text"].ToString() + "'", "Text", DataViewRowState.CurrentRows);
                Repeater _rptChild = e.Item.FindControl("rptChild") as Repeater;
                _rptChild.DataSource = _dv;
                _rptChild.DataBind();
            }

        }

        public void rptChild_ItemCreated(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {

                Label childLabel = e.Item.FindControl("lblChildData") as Label;
                DataRowView drv = (DataRowView)e.Item.DataItem;
                childLabel.Text = drv["Text"].ToString();

            }
        }

        public void rptMain_ItemCommand(object sender, RepeaterCommandEventArgs e)
        {
            Console.Write("fdasdfsa");
        }

Solution

  • The repeater is going to be re-created during a postback. That's why the OnItemCreated event is firing. The reason the OnItemCommand is not being called is because an exception is occurring in your OnItemCreated event. The property

    e.Item.DataItem
    

    is not available in a postback and returns null. So when you try to access it with

    ibtn.CommandArgument = drv["CommandValue"].ToString();
    

    you end up with a NullReferenceException.