Gestore di eventi OnCheckedChanged di asp: la casella di controllo non si attiva quando la casella di controllo è deselezionata

StackOverflow https://stackoverflow.com/questions/1404528

  •  05-07-2019
  •  | 
  •  

Domanda

Ho un ripetitore, in ogni ItemTemplate del ripetitore c'è un'asp: checkbox con un set di gestori di eventi OnCheckedChanged. Le caselle di controllo hanno la proprietà AutoPostBack impostata su true. Quando viene selezionata una delle caselle di controllo, il gestore eventi viene attivato. Quando uno è deselezionato, il gestore eventi non si attiva.

Qualche idea sul perché l'evento non si attivi e su come posso attivarlo? Grazie.

Codice ripetitore semplificato:

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

La collezione è legata al ripetitore come segue:

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

Il gestore eventi OnItemDataBound è il seguente:

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

Il gestore eventi OnCheckedChanged è il seguente:

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. Se qualcuno può anche dirmi perché il markdown non funziona correttamente per me ...

È stato utile?

Soluzione

Questo perché la gerarchia dei controlli (e le caselle di controllo in particolare) non esistono quando ASP.NET esegue la parte Control events del ciclo di vita della pagina ASP.NET, come è stato creato nelle fasi successive PreRender . Vedere Panoramica del ciclo di vita della pagina ASP.NET per una panoramica più dettagliata della sequenza di eventi.

Vorrei sbagliare a proposito della cautela per il consiglio di @ bleeeah, perché stai assegnando un valore a CheckBox.Checked all'interno di rptLinkedItems_ItemDataBound , che avrebbe anche causa l'esecuzione del gestore eventi:


chkLinked.Checked = IsItemLinked(item);

Invece, sposta:


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

Nel gestore di eventi Page.Load .

Altri suggerimenti

Prova a utilizzare AutoPostBack = " true " in questo modo:

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

Prova a iscriverti nuovamente all'evento CheckedChanged nell'evento ItemDataBound,

chkLinked.CheckedChanged += new EventHandler(chkLinked_CheckedChanged);

Usa AutoPostBack = " true " in questo modo:

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

Iscriviti all'evento CheckChanged nel tuo Page_Init.

Devi definire eventhandler per la lista di controllo dal comando dell'elemento ripetitore, quindi all'interno del comando dell'elemento ripetitore, scorrere gli elementi dell'elenco di controllo e ottenere gli elementi controllati.

Nella pagina .aspx puoi usare Ajax e updatepanel per lanciare il gestore degli eventi, ma tieni presente che devi definire lo scriptmanage al di fuori del ripetitore.

// checklisk checkedchange eventhandler

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

e voce di comando ripetitore elemento: // itera gli elementi della checklist e rileva spuntati

    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] + ",";
            }
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top