当asp:checkbox未被选中时,OnCheckedChanged事件处理程序不会触发。

28

我有一个Repeater,在Repeater的每个ItemTemplate中都有一个带有OnCheckedChanged事件处理程序的asp:checkbox。这些复选框的AutoPostBack属性设置为true。当任何一个复选框被选中时,事件处理程序就会触发。但是当任何一个未被选中时,事件处理程序不会触发。

有任何想法为什么事件不会触发,以及如何使其触发?谢谢。

简化的Repeater代码:

<asp:Repeater ID="rptLinkedItems" runat="server">            
    <ItemTemplate>      
    <asp:CheckBox ID="chkLinked" runat="server" 
     Checked="false" OnCheckedChanged="chkLinked_CheckedChanged" />
    </ItemTemplate>    
</asp:Repeater>
集合被绑定到repeater如下:
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);
}

OnItemDataBound事件处理程序如下:

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());
    }
}

OnCheckedChanged事件处理程序如下:

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);
}

顺便说一句,如果有人能告诉我为什么Markdown对我不起作用......


@Jibberish:回复你的P.S.。你做错了 ;)。试着以编辑模式打开这个问题,看看我做了哪些更改。关键点是在代码前加上4个空格,编辑器会在右侧面板中指示你这样做。 - AnthonyWJones
谢谢Anthony,很抱歉我在编辑器中错过了那个。 - Jason
6个回答

44

尝试像这样使用 AutoPostBack="true"

<asp:CheckBox ID="chkLinked" runat="server" Checked="false"
    OnCheckedChanged="chkLinked_CheckedChanged" AutoPostBack="true"/>

我已经正确完成了其中的一部分,AutoPostBack实现了我的目标! - Vasily Hall
完美的解决方案,因为AutoPostBack在您更改复选框状态后刷新页面,因此您可以正确地处理属性checkbox_checkchanged。 - Emanuel Pirovano

18

这是因为在ASP.NET执行ASP.NET页面生命周期的Control events部分时,控件层次结构(特别是复选框)不存在,因为您是在稍后的PreRender阶段创建它们。有关事件序列的更详细概述,请参见ASP.NET Page Life Cycle Overview

对于@bleeeah的建议,我会保持谨慎态度,因为您正在rptLinkedItems_ItemDataBound中分配一个值给CheckBox.Checked,这也会导致事件处理程序执行:


chkLinked.Checked = IsItemLinked(item);

相反,移动:


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

进入Page.Load事件处理程序。


谢谢,Rabid。除了之前提到的重新订阅事件外,我已经完成了这个操作,现在一切都按照预期工作。 - Jason
没问题,你能给我的问题投个赞吗?https://dev59.com/oXM_5IYBdhLWcg3wdy5g? 我非常需要一些建议 :) - Rabid

6
在您的OnItemDataBound事件中,尝试重新订阅CheckChanged事件。
chkLinked.CheckedChanged += new EventHandler(chkLinked_CheckedChanged);

1
那似乎解决了问题,谢谢。但我不太清楚为什么,有人能给我解释一下吗? - Jason
1
它能够工作是因为动态控件的事件处理程序必须在每次重建页面时重新连接。 - Carl
除非您在Init中执行它,这样框架就会处理它。 - Jan Jongboom
谢谢,这个解决了我的问题。我已经将它添加到PageLoad函数中,所以我可以将这个oncheckchanged事件链接到我的函数。 - arzucaki

3

像这样使用 AutoPostBack="true"

<asp:CheckBox ID="chkLinked" runat="server" AutoPostBack="true"
    Checked="false" OnCheckedChanged="chkLinked_CheckedChanged" />

谢谢,这对我很有帮助 :) - Barry Michael Doyle

2
在 Page_Init 中订阅 CheckChanged 事件。

0

你需要在重复器项命令之外定义清单的事件处理程序,然后在重复器项命令内部遍历清单项并获取选中的项。

在 .aspx 页面中,你可以使用 Ajax 和 UpdatePanel 来触发事件处理程序,但请记住,你必须在重复器之外定义 ScriptManager。

// 清单选中更改事件处理程序

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

和项目重复器命令项: // 迭代检查清单项目并检测已选中的

    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] + ",";
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接