28

I have a repeater, in each ItemTemplate of the repeater is an asp:checkbox with an OnCheckedChanged event handler set. The checkboxes have the AutoPostBack property set to true. When any of the checkboxes is checked, the event handler fires. When any is unchecked, the event handler does not fire.

Any idea why the event does not fire, and how I mgiht make it fire? Thanks.

Simplified repeater code:

<asp:Repeater ID="rptLinkedItems" runat="server">            
    <ItemTemplate>      
    <asp:CheckBox ID="chkLinked" runat="server" 
     Checked="false" OnCheckedChanged="chkLinked_CheckedChanged" />
    </ItemTemplate>    
</asp:Repeater>

The collection is bound to the repeater as follows:

protected override void OnPreRenderComplete(EventArgs e)
{
    if (!Page.IsPostBack)
    {
        m_linkedItems = GetLinkedItems();
        rptLinkedItems.DataSource = GetLinkableItems();
        rptLinkedItems.ItemDataBound += new RepeaterItemEventHandler
               (rptLinkedItems_ItemDataBound);
        rptLinkedItems.DataBind();
    }

    base.OnPreRenderComplete(e);
}

The OnItemDataBound event handler is as follows:

private void rptLinkedItems_ItemDataBound(Object sender, RepeaterItemEventArgs args)
{
    if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
    {
        CategoryItem item = args.Item.DataItem as CategoryItem;

        Literal litItemName = args.Item.FindControl("litItemName") as Literal;
        CheckBox chkLinked = args.Item.FindControl("chkLinked") as CheckBox;

        litItemName.Text = item.Text;

        chkLinked.Checked = IsItemLinked(item);
        chkLinked.AutoPostBack = true;
        chkLinked.InputAttributes.Add("Value", item.Id.ToString());
    }
}

The OnCheckedChanged event handler is as follows:

protected void chkLinked_CheckedChanged(Object sender, EventArgs args)
{
    CheckBox linkedItem = sender as CheckBox;
    Boolean itemState = linkedItem.Checked;
    Int32 itemId = Int32.Parse(linkedItem.InputAttributes["Value"].ToString());
    DataAccessLayer.UpdateLinkedItem(m_linkingItem, Utilities.GetCategoryItemFromId(itemId), itemState);
}

P.S. If someone can also tell me why markdown doesn't work correctly for me...

Tobias Tengler
  • 6,848
  • 4
  • 20
  • 34
Jason
  • 3,599
  • 10
  • 37
  • 52
  • @Jibberish: RE: your P.S. You weren't doing it right. ;) Try opening this question in edit mode and see what changes I made. Key point 4 spaces to prefix code, which the editor instructs you to do in the right hand panel. – AnthonyWJones Sep 10 '09 at 10:52
  • Thanks Anthony, and sorry I missed that in the editor. – Jason Sep 10 '09 at 10:58

6 Answers6

44

Try usingAutoPostBack="true" like this:

<asp:CheckBox ID="chkLinked" runat="server" Checked="false"
    OnCheckedChanged="chkLinked_CheckedChanged" AutoPostBack="true"/>
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
tommy
  • 1,006
  • 1
  • 11
  • 13
18

This is because the control hierarchy (and the check boxes in particular) don't exist when ASP.NET executes the Control events portion of the ASP.NET page life cycle, as you had created them in the later PreRender stages. Please see ASP.NET Page Life Cycle Overview for more detailed overview of the event sequence.

I would err on the side of caution for @bleeeah's advice, for you're assigning a value to CheckBox.Checked inside rptLinkedItems_ItemDataBound, which would also cause the event handler to execute:


chkLinked.Checked = IsItemLinked(item);

Instead, move:


if (!Page.IsPostBack)
   {
      m_linkedItems = GetLinkedItems();
      rptLinkedItems.DataSource = GetLinkableItems();
      rptLinkedItems.ItemDataBound += new RepeaterItemEventHandler
          (rptLinkedItems_ItemDataBound);
      rptLinkedItems.DataBind();
   }

Into the Page.Load event handler.

Rabid
  • 2,984
  • 2
  • 25
  • 25
  • Thanks, Rabid. Have done that in addition to re-subscribing to the event as mentoined earlier and everything now works exactly as intended. – Jason Sep 10 '09 at 11:22
  • No problem, could you please vote up my question http://stackoverflow.com/questions/1368403? I'm desperate for some advice :) – Rabid Sep 10 '09 at 11:55
6

Try re-subscribing to the CheckChanged event in your OnItemDataBound event ,

chkLinked.CheckedChanged += new EventHandler(chkLinked_CheckedChanged);
bleeeah
  • 3,534
  • 19
  • 25
  • 1
    That appears to have solved the problem, thanks. I'm not clear on why though, can anyone enlighten me? – Jason Sep 10 '09 at 10:58
  • 1
    It works because the event handlers of dynamic controls must be wired up every time the page is rebuilt. – Carl Sep 10 '09 at 10:59
  • Unless you do it in the Init, that way the framework takes care of this. – Jan Jongboom Sep 10 '09 at 11:01
  • Thank you this one has solved my problem. I have added this into PageLoad function so i can link this oncheckchanged event to my fuction. – arzucaki Jan 02 '20 at 18:12
3

Use AutoPostBack="true" like this:

<asp:CheckBox ID="chkLinked" runat="server" AutoPostBack="true"
    Checked="false" OnCheckedChanged="chkLinked_CheckedChanged" />
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
2

Subscribe to the CheckChanged event in your Page_Init.

Jan Jongboom
  • 26,598
  • 9
  • 83
  • 120
0

You have to define eventhandler for checklist out of repeater item command, then inside the repeater item command, go through checklist items and get checked items.

In the .aspx page you can use Ajax and updatepanel to fire eventhandler, but keep in mind you have to define scriptmanage outside of repeater.

// checklisk checkedchange eventhandler

protected void chkLinked_CheckedChanged(Object sender, EventArgs args)
        {
        }

and item repeater command item: // iterate checklist items and detect checked

    protected void Repeater1_ItemCommand(object sender, RepeaterCommandEventArgs e)
    {
        CheckBoxList cbl = (CheckBoxList)e.Item.FindControl("CheckBoxList1");
        cbl.SelectedIndexChanged += new EventHandler(chkLinked_CheckedChanged);

        string name = "";
        for (int i = 0; i < cbl.Items.Count; i++)
        {
            if (cbl.Items[i].Selected)
            {
                name += cbl.Items[i].Text.Split(',')[0] + ",";
            }
        }
    }
Shaahin
  • 1,195
  • 3
  • 14
  • 22