2012-07-30 35 views
6

Ho cercato estesamente su questo, ma non riesco a trovare la soluzione al mio problema. Sto cercando di chiamare una funzione nel codice retrostante di una pagina da un controllo utente su quella pagina.Event Handler è sempre nullo

Ho un'applicazione Web che utilizza una pagina principale. Sto aggiungendo un controllo utente che ho scritto a una delle pagine di contenuto. Ho aggiunto il controllo utente alla pagina di aspx trascinandolo dalla casella degli strumenti. Sono in grado di vedere il controllo dell'utente dal codice sottostante, ma non riesco ad accedere alle funzioni pubbliche. Per risolvere questo problema, ho creato un oggetto del controllo utente nel codice sottostante e ho utilizzato la funzione LoadControl. Tutto ciò sembra funzionare bene.

Il problema che sto avendo è quando sto provando ad agganciare l'EventHandler dalla pagina aspx al controllo utente. Tutto si compila e funziona bene, ma non vedo nulla sulla pagina. Penso che il problema è che EventHandler è sempre nullo.

controllo utente Codice

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

Pagina Codice

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

Chiunque può vedere che cosa sto facendo male?

MODIFICA: questo problema è stato risolto. I frammenti di codice sopra sono ora funzionali. Se qualcuno incontra il problema che ho riscontrato, puoi modellare il codice qui sopra. Assicurati che sia AutoEventWireup="true" in entrambe le pagine aspx e ascx. Grazie June Paik per la tua soluzione. Grazie Diego De Vita per il tuo contributo.

+0

'if (BuyerSelected! = Null) {BuyerSelected (this, e); } 'Non farlo mai! Questo codice crea una condizione di competizione. Questo è l'idioma corretto: 'var h = BuyerSelected; if (h! = null) h (questo, e); ' – cdhowie

+0

Ho scritto qualcos'altro solo pochi secondi fa .. mi dispiace .. in realtà ho visto il tuo commento e forse non sono d'accordo. Io sparo sempre la classe dell'evento in questo modo. Significa: chiama i gestori di eventi nel caso in cui ci siano eventi collegati all'evento. ora non ho letto attentamente la domanda, quindi non ho una risposta. Sto solo dicendo che il tuo ultimo commento non è corretto –

+0

Mi chiedo se tu abbia davvero dichiarato lbBuyerList_SelectedIndexChanged come gestore di un tale evento sul controllo asp.net modificando l'attributo tag corretto in modo dichiarativo nell'ascx. Puoi provare a utilizzare i breakpoint su ogni fase (partendo dal corpo di quel metodo) e scoprire durante il debug se viene chiamato quel codice. –

risposta

2

Ho combattuto con gli eventi per un po 'di tempo. Oggi li creo sempre così perché è l'unico modo in cui so che funziona. Non hanno provato con il codice, ma qui va comunque:

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

Nella pagina padre si può chiamare la funzione allo stesso modo si sta facendo già.

+0

Grazie per il diverso approccio. Ho provato a utilizzare questo codice ma continuo a scoprire che l'oggetto "gestore" è nullo. –

+0

Questa è un'ipotesi, ma hai provato a completare il page_load della pagina dei genitori in un if (! Page.IsPostback)? –

+0

Ho cambiato il mio codice per utilizzare il metodo che hai descritto sopra. All'inizio non ha funzionato. Ho dovuto rendere AutoEventWireup = "true" in entrambe le pagine aspx e ascx. Grazie mille per il tuo aiuto. Pubblicherò il codice per gli altri da utilizzare se si imbattono in una situazione come quella che ho fatto io. –

1

Potrebbe essere che Page_Load sia troppo tardi nel ciclo di vita della pagina per utilizzare LoadControl e iscriversi all'evento. Cosa succede se sposti quel codice nel metodo Page_Init?

+0

potrebbe essere un buon punto. Di solito aggiungo controlli utente sull'ascx dichiarativo, non a livello di codice. –