2012-07-30 22 views
6

He buscado mucho sobre esto, pero no puedo encontrar la solución a mi problema. Intento llamar a una función en el código detrás de una página desde un control de usuario en esa página.Controlador de eventos es siempre nulo

Tengo una aplicación web que utiliza una página maestra. Estoy agregando un control de usuario que escribí en una de las páginas de contenido. Agregué el control de usuario a la página aspx arrastrándolo y soltándolo desde la caja de herramientas. Puedo ver el control del usuario desde el código, pero no puedo acceder a las funciones públicas. Para solucionar ese problema, creé un objeto del control de usuario en el código subyacente y usé la función LoadControl. Todo eso parece funcionar bien.

El problema que tengo es cuando intento conectar el EventHandler desde la página aspx al control de usuario. Todo se compila y funciona perfectamente, pero no veo que pase nada en la página. Creo que el problema es que EventHandler siempre es nulo.

Código de Control de Usuario

public partial class ucBuyerList : System.Web.UI.UserControl 
{ 
    public delegate void BuyerSelectedEventHandler(object sender, EventArgs e); 
    public event BuyerSelectedEventHandler BuyerSelected; 

    private string name = ""; 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    private string auid = ""; 
    public string AUID 
    { 
     get { return auid; } 
     set { auid = value; } 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    private void OnBuyerSelected(EventArgs e) 
    { 
     if (BuyerSelected != null) 
     { 
      BuyerSelected(this, new EventArgs()); 
     } 
    } 

    protected void lbBuyerList_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     SetNameAndAUID(); 
     OnBuyerSelected(e); 
    } 

    private void SetNameAndAUID() 
    { 
     name = lbBuyerList.SelectedItem.Text; 
     auid = lbBuyerList.SelectedItem.Value; 
    } 
} 

Padres Página de códigos

public partial class frmBuyerInformation : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     Master.changePageTitle("Buyer Information"); 
     buyerList.BuyerSelected += new ucBuyerList.BuyerSelectedEventHandler(buyerListControl_BuyerSelected); 
    } 

    void buyerListControl_BuyerSelected(object sender, EventArgs e) 
    { 
     DisplayBuyerInformation(); 
    } 

    public void DisplayBuyerInformation() 
    { 
     tbName.Text = buyerList.Name; 
     tbAUID.Text = buyerList.AUID; 
    } 
} 

Puede alguien ver lo que estoy haciendo mal?

EDITAR: Este problema se ha resuelto. Los snippits de código anteriores ahora son funcionales. Si alguien se encuentra con el problema que tuve, puede modelar el código anterior. Asegúrese de que AutoEventWireup="true" en las páginas aspx y ascx. Gracias June Paik por tu solución. Gracias Diego De Vita por tu aporte también.

+0

'if (¡Selector de comprador! = Nulo) {Selector de comprador (esto, e); } '¡Nunca hagas esto! Este código crea una condición de carrera. Esta es la expresión apropiada: 'var h = BuySelected; if (h! = null) h (this, e); ' – cdhowie

+0

Escribí algo más hace unos segundos..sobre todo ... Vi tu comentario y tal vez no estoy de acuerdo. Siempre disparo la clase de evento de esa manera. Significa: llamar a los controladores de eventos en caso de que haya alguno adjunto al evento. ahora no leí atentamente la pregunta, así que no tengo respuesta. Solo digo que su último comentario no es correcto –

+0

Me pregunto si realmente declaró lbBuyerList_SelectedIndexChanged como el controlador de tal evento en el control asp.net modificando el atributo de etiqueta apropiado declarativamente en el archivo ascx. Puede intentar usar puntos de interrupción en cada etapa (comenzando desde el cuerpo de ese método) y descubrir durante la depuración si se llama a ese código. –

Respuesta

2

He estado luchando con eventos durante bastante tiempo también. Hoy en día siempre los creo de esta manera porque es la única forma en que sé que funciona. no se han probado con su código, pero aquí va de todos modos:

public partial class ucBuyerList : System.Web.UI.UserControl 
{ 
    public delegate void BuyerSelectedEventHandler(object sender, EventArgs e); 

    public event BuyerSelectedEventHandler BuyerSelected; 

    public string Name; 
    public string AUID; 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     //Select the first buyer in the list when the user control loads 

     if (!IsPostBack) 
     { 
      lbBuyerList.SelectedIndex = 0; 
     } 
    } 

    private void OnBuyerSelected(EventArgs e) 
    { 
     BuyerSelectedEventHandler handler = BuyerSelected; 
     if (handler != null) 
     { 
      handler(this, new EventArgs()); 
     } 
    } 

    protected void lbBuyerList_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     Name = lbBuyerList.SelectedItem.Text; 
     AUID = lbBuyerList.SelectedItem.Value; 
     OnBuyerSelected(e); 
    } 
} 

En la página principal sólo se puede llamar a su función de la misma manera que lo estás haciendo ya.

+0

Gracias por el diferente enfoque. Intenté usar este código pero todavía encuentro que el objeto "manejador" es nulo. –

+0

Sin embargo, esto es una suposición descabellada, pero ¿ha intentado envolver la página page_load de su padre en un if (! Page.IsPostback)? –

+0

Cambié mi código para usar el método que describió anteriormente. No funcionó al principio. Tuve que hacer que AutoEventWireup = "true" en las páginas aspx y ascx. Muchas gracias por su ayuda. Publicaré el código para que otros lo usen si se topan con una situación como yo. –

1

Es posible que Page_Load sea demasiado tarde en el ciclo de vida de la página para usar LoadControl y suscribirse al evento. ¿Qué sucede si mueve ese código al método Page_Init?

+0

que podría ser un buen punto. Usualmente agrego controles de usuario en la declaración ascx, no programáticamente. –

Cuestiones relacionadas