1

J'ai déjà posé cette question, mais malheureusement, j'ai toujours des problèmes et le problème n'a pas été résolu. Fondamentalement, je crée dynamiquement un LinkButton pour chaque ligne d'une table que je génère, et ce bouton a la tâche de supprimer la ligne avec l'ID correspondant de la base de données. Pour ce faire, il me semble que j'ai besoin d'assigner une LinkButton à une commande pour qu'elle apparaisse dans l'événement quand on clique dessus. Le problème est, quand le bouton a cliqué sur le programme jamais va dans la commande - j'ai mis des points d'arrêt là et il ne va jamais dans eux. Voici mon code:LinkButton créé dynamiquement n'entrera pas dans l'événement de commande

protected void Page_Init(object sender, EventArgs e) 
     { 
      if (Request.QueryString["id"] != null) 
      { 

       ColorConverter conv = new ColorConverter(); 
       string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString; 
       TPRDBDataContext dc = new TPRDBDataContext(); 
       DataContext db = new DataContext(connection); 
       Table<SageAccount> SageAccount = db.GetTable<SageAccount>(); 
       Table<InvoiceItem> InvoiceItem = db.GetTable<InvoiceItem>(); 
       Table<Invoice> Invoice = db.GetTable<Invoice>(); 
       Boolean alloweditting = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.alloweditting).Single(); 
       if (alloweditting == false) 
       { 
        dtlsInsert.Visible = false; 
        modalPanel.Visible = false; 
       } 
       int sagepk = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.sageaccount).Single(); 
       lblSageID.Text = (from s in dc.SageAccounts where s.ID == sagepk select s.SageID).Single(); 
       lblDate.Text = DateTime.Now.ToShortDateString(); 


       Table table = new Table(); 
       table.Width = Unit.Percentage(100); 
       table.GridLines = (GridLines)3; 

       TableHeaderRow header = new TableHeaderRow(); 
       header.BackColor = (System.Drawing.Color)conv.ConvertFromString("#EDEDED"); 
       foreach (string header2 in new string[] { "", "Quantity", "Rate", "Description", "Nominal Code", "Subtotal" }) 
       { 
        TableCell cell = new TableCell(); 
        cell.Text = header2; 
        header.Cells.Add(cell); 
       } 

       table.Rows.Add(header); 

       var data = (from s in dc.InvoiceItems where s.invoiceid.ToString() == Request.QueryString["id"].ToString() select s); 
       foreach (var x in data) 
       { 

        TableRow row = new TableRow(); 
        if (x.invoicetext == null) 
        { 
         decimal total; 
         try 
         { 
          total = (decimal)x.rate * (decimal)x.quantity; 
         } 
         catch 
         { 
          total = 0; 
         } 
         int i = 0; 
         foreach (string columnData in new string[] { x.id.ToString(), x.quantity.ToString(), x.rate.ToString(), x.description, x.nominalcode, total.ToString("N2") }) 
         { 
          TableCell cell = new TableCell(); 
          { 
           if (i == 0) 
           { 
            LinkButton lnkdel = new LinkButton(); 
            lnkdel.Text = "Delete"; 
            lnkdel.ID = "lnkDel" + Guid.NewGuid(); 

            if (alloweditting == false) 
            { 
             lnkdel.Enabled = false; 
            } 
            lnkdel.Font.Bold = false; 
            lnkdel.CommandArgument = x.id.ToString(); 
            //lnkdel.Command += lnkdel_Command; 
            //lnkdel.Command += new CommandEventHandler(this.lnkdel); 
            cell.Controls.Add(lnkdel); 
            i++; 
           } 
           else 
           { 
            cell.Text = columnData; 
           } 


          } 

          row.Cells.Add(cell); 
         } 



         runningtotal = runningtotal + total; 

        } 
        else 
        { 
         int i = 0; 

         foreach (string columnData in new string[] { x.id.ToString(), x.invoicetext }) 
         { 
          TableCell cell = new TableCell(); 

          if (i == 0) 
          { 
           LinkButton lnkdel = new LinkButton(); 
           lnkdel.Text = "Delete"; 
           lnkdel.ID = "lnkDel" + Guid.NewGuid(); 

           if (alloweditting == false) 
           { 
            lnkdel.Enabled = false; 
           } 
           lnkdel.Font.Bold = false; 
              //lnkdel.Command += lnkdel_Command; 
            //lnkdel.Command += new CommandEventHandler(this.lnkdel); 
           lnkdel.CommandArgument = x.id.ToString(); 



           cell.Controls.Add(lnkdel); 
           i++; 
          } 
          else 
          { 
           cell.Text = columnData; 
           cell.ColumnSpan = 5; 
          } 
          row.Cells.Add(cell); 

         } 

        } 

        switch (x.formatoptions) 
        { 
         case 1: 
          row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black"); 
          row.Font.Bold = false; 
          break; 
         case 2: 
          row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black"); 
          row.Font.Bold = true; 
          break; 
         case 3: 
          row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red"); 
          row.Font.Bold = false; 
          break; 
         case 4: 
          row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red"); 
          row.Font.Bold = true; 
          break; 
        } 
        table.Rows.Add(row); 
       } 

       TableFooterRow row2 = new TableFooterRow(); 
       TableCell cell2 = new TableCell(); 
       cell2.Text = "<span style\"text-align: right; width: 100%;\">Total = <b>" + runningtotal.ToString("N2") + "</b></span>"; 
       cell2.ColumnSpan = 6; 
       row2.Cells.Add(cell2); 
       table.Rows.Add(row2); 

       var update = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s).Single(); 
       update.total = runningtotal; 

       dc.SubmitChanges(); 
       datatable.Controls.Clear(); 
       datatable.Controls.Add(table); 
      } 
      else 
      { 
       Response.Redirect("Invoices.aspx"); 
      } 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 



     } 


     protected void lnkdel_Command(object sender, CommandEventArgs e) 
     { 
      string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString; 


      using (SqlConnection conn = new SqlConnection(connection)) 
      { 
       SqlCommand comm = new SqlCommand("DELETE FROM InvoiceItem WHERE id = @id", conn); 
       comm.Parameters.AddWithValue("@id", e.CommandArgument.ToString()); 
       conn.Open(); 
       try 
       { 
        comm.ExecuteNonQuery(); 
       } 
       catch (Exception ex) 
       { 
        Response.Write(ex); 
       } 
      } 
    } 

Remarque J'ai commenté sur 2 des lignes cruciales pour l'affichage ici, juste pour dire que je l'ai essayé les deux lignes qui est mis en commentaire et aucun travail :(

+0

Ceci est un moyen de résoudre ce problème des événements ci-joint dynamique. il y a d'autres, vous devez comprendre le cycle de vie de la page pour faire fonctionner ce genre de choses, google 'cycle de vie de la page asp.net' pour en savoir plus ou lire http://stackoverflow.com/questions/141169/c-dynamically-created- linkbutton-command-event-handler – Hogan

Répondre

1

Vous devez ajouter les contrôles sur chaque postback. Vous semblez être que leur création sur le get initial (que la vérification de la chaîne de requête). sur le poste arrière, ces contrôles ne sont recréés donc pas événement se déclenche.

Il est notoirement contre-intuitif, mais alors que ASP.NET se penche en arrière pour vous faire croire que l'instance de votre classe de page est la même entre deux requêtes HTTP, la réalité est qu'elles ne sont pas les mêmes. Une nouvelle instance est créée à chaque fois. Il semble que vous essayiez d'éviter d'ajouter les contrôles générés dynamiquement plusieurs fois - en pensant que vous ne voulez pas de doublons. La réalité est que vous n'aurez jamais de doublons lors de l'ajout de contrôles générés dynamiquement dans une méthode de cycle de vie telle que OnInit() car il s'agit toujours d'une nouvelle instance de la classe de page, et donc les contrôles générés dynamiquement ont disparu.

La raison pour laquelle cela est généralement transparent pour les développeurs est que tous les contrôles dans le front de code sont automatiquement régénérés pour vous à la fois sur la demande initiale et chaque post-retour. Pour vos commandes, vous dynamiquement créés arriver à cette ligne:

if (Request.QueryString["id"] != null) { ... } 

À moins que vous faites quelque chose attribut spécial, que « id » ne sera pas dans la chaîne de requête sur le postback. Cela signifie qu'aucune partie du code du bloc if ne sera exécutée à la publication (lorsque votre événement se déclenche réellement). Cela signifie que votre if -check en haut doit être supprimé complètement. Tous ce code doit être exécuté pour chaque requête (GET et POST).

+0

Hmm, donc fondamentalement au-dessus de toutes les instructions if dans la méthode Page_Init, pour initialiser la table? Qu'en est-il du bouton de lien, vu qu'ils sont tous générés dynamiquement pour chaque ligne? – Chris

+0

@Chris, réponse mise à jour. –

+0

Mon pote, dans le cas de l'utilisateur accédant à la page sans la chaîne de requête, l'erreur de page ne serait pas alors que beaucoup de mon code fait référence à la chaîne de requête? Bien que je suppose que je pourrais l'enfermer dans un essai/catch, mais serais-je finir dans exactement la même situation si oui? – Chris

0

Il suffit de dire que j'ai créé une solution de contournement - créant simplement un simple lien vers la page, ainsi que d'une chaîne de requête contenant l'identifiant de la ligne à supprimer