2008-09-18 27 views
6

J'ai un contrôle utilisateur qui est chargé dynamiquement dans la page en utilisant le code suivant dans Init de la page.Le contrôle utilisateur créé dynamiquement ne peut pas gérer les événements sur PostBack

Dim oCtl As Object 
oCtl = LoadControl("~/Controls/UserControl1.ascx") 

oCtl.Id = "UserControl11" 
PlaceHolder1.Controls.Clear() 
PlaceHolder1.Controls.Add(oCtl) 

Le contrôle utilisateur contient également un bouton et je suis incapable de capturer le clic du bouton dans le contrôle utilisateur.

Répondre

1

Quelques questions:

  1. À quel moment du cycle de vie de la page que vous chargez le contrôle?
  2. Où est le code du gestionnaire d'événements? Dans le contrôle lui-même ou essayez-vous de l'accrocher à la page?
  3. Qu'avez-vous fait jusqu'ici pour câbler l'événement?

Enfin, les lignes directrices de style pour .Net recommandent spécifiquement contre en utilisant des verrues comme le préfixe o la Hongrie ne en oCtl, et vous devez taper comme un contrôle plutôt qu'un objet.

+0

Point accepté pour le préfixe hongrois, gardez cela à l'esprit pour l'avenir. Je vais coller le code complet dans un commentaire ci-dessous. J'apprécierais vos commentaires –

-1

Vous voulez charger uniquement le contrôle lorsqu'ils ne sont pas IsPostBack

3

Assurez-vous de charger le contrôle sur tous les postback - si le contrôle est pas dans l'arborescence des contrôles lorsque les messages de page en arrière, ASP.NET ne sera pas augmenter l'événement de clic sur le bouton.

5

Vous devez vous assurer que le contrôle existe sur la page avant que .NET ne passe à l'étape "Traitement des événements de publication" du cycle de vie de la page. Puisque le contrôle est ajouté de manière dynamique, vous devez vous assurer qu'à chaque publication, vous recréerez ce contrôle afin qu'il puisse trouver le contrôle permettant de déclencher l'événement.

0

Voici le code complet pour la page

Partial Class DynamicLoad 
    Inherits System.Web.UI.Page 

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init 
     If IsPostBack Then 
      If Not (Session("ctl") Is Nothing) Then 
       Dim oCtl As Object 
       oCtl = Session("ctl") 
       PlaceHolder1.Controls.Add(oCtl) 
      End If 
     End If 
    End Sub 


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not IsPostBack Then 
      Dim oCtl As Object 
      oCtl = LoadControl("~/Controls/UserControl1.ascx") 

      oCtl.Id = "UserControl11" 
      PlaceHolder1.Controls.Clear() 
      PlaceHolder1.Controls.Add(oCtl) 

      Session("ctl") = oCtl 
     End If 
    End Sub 
End Class 

Voici le code complet pour le contrôle de l'utilisateur

Partial Class UserControl1 
    Inherits System.Web.UI.UserControl 
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Label1.Text = "This is Text AFTER Post Back in User Control 1" 
    End Sub 
End Class 
0

Depuis que vous avez demandé, j'écrire votre événement init comme celui-ci. Je vais laisser l'événement Load comme un exercice:

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init 
    If IsPostBack AndAlso Session("ctl") IsNot Nothing Then 
     Dim MyControl As Control = Session("ctl") 
     PlaceHolder1.Controls.Add(MyControl) 
    End If 
End Sub 

Je viens aussi avec un meilleur nom que « MyControl », mais comme je ne sais pas ce que le contrôle fait que cela aura à faire.

+0

Mais cela ne résout pas réellement mon problème de postback depuis le contrôle –

0

Je ne sais pas sans l'essayer, mais que faire si vous câblez par programme le gestionnaire d'événements du bouton?

AddHandler Button1.Click, AddressOf Button1_Click 

Si cela ne fait rien, je sais qu'il est moins efficace, mais si vous n »: dans Init ou Load (pas sûr), par exemple, dans le code-behind pour le contrôle de l'utilisateur lui-même, t stockez l'instance de contrôle utilisateur dans Session et toujours la recréer dans Page_Init à chaque fois?

10

Il y a un certain nombre de choses que vous faites qui ne sont pas nécessaires et qui causent probablement vos problèmes.

Ce sont:

  1. Il n'y a pas besoin de stocker l'objet de contrôle de la session.Le contrôle lui-même doit utiliser ViewState et l'état de session pour stocker les informations requises, et non l'instance entière.
  2. Vous ne devriez pas vérifier PostBack lors de la création du contrôle. Il doit être créé à chaque fois pour permettre à ViewState de fonctionner et à l'événement d'être câblé.
  3. Les contrôles chargés après le chargement de ViewState ont souvent du mal à fonctionner correctement; évitez donc de charger le produit pendant l'événement Chargement de page, dans la mesure du possible.

Ce code fonctionne pour moi:


Default.aspx

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Test_User_Control._Default" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"><title></title></head> 
<body> 
    <form id="form1" runat="server"> 
     <asp:PlaceHolder ID="PlaceHolder1" runat="server" /> 
    </form> 
</body> 
</html> 

Default.aspx.vb

Partial Public Class _Default 
    Inherits System.Web.UI.Page 

    Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init 

     Dim control As Control = LoadControl("~/UserControl1.ascx") 
     PlaceHolder1.Controls.Add(control) 

    End Sub 
End Class 

UserControl1.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UserControl1.ascx.vb" Inherits="Test_User_Control.UserControl1" %> 
<asp:Label ID="Label1" Text="Before Button Press" runat="server" /> 
<asp:Button ID="Button1" Text="Push me" runat="server" /> 

UserControl1.ascx.vb

Public Partial Class UserControl1 
    Inherits System.Web.UI.UserControl 

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Label1.Text = "The button has been pressed!" 
    End Sub 

End Class 

2

Je viens de vivre le même problème que vous avez fait, sauf que dans mon cas, je n'ai pas utilisé un session pour stocker le contrôle.

Dans mon cas, je trouve le problème dans cette ligne:

PlaceHolder1.Controls.Clear()

Ce que je l'ai fait est créé un contrôle des enfants et de les ajouter au récipient parent sur Page_Init, puis traité certains gestionnaires d'événements et après que sur Page_PreRender j'ai recréé toute la liste avec les données mises à jour.

La solution que j'ai utilisée dans ce cas était de créer la collection de contrôle une fois - dans la première phase du cycle de la page.

+0

oui, c'était aussi mon problème :) thanx – Marko