2011-10-12 4 views
0

J'ai créé un contrôle serveur personnalisé. Cela a l'air génial et le HTML rendu est aussi comme il se doit. Je l'ai d'abord fait étendre le ControlContainer et maintenant il étend le WebControl (les deux se comportent de la même manière.) Il a deux propriétés, ImageUrl et Text. Essentiellement, il va afficher une balise HTML générique avec des balises et.Le contrôle du serveur personnalisé ASP.Net ne déclenche pas l'événement personnalisé

Mon problème est que l'événement ServerClick qui est exposé (par NamingContainer je crois) ne semble pas se déclencher. Si j'ajoute l'un des boutons ASP (Link, Image ou Regular) et que je m'associe à cet événement Click, il se déclenche mais j'ai bien sûr du contenu supplémentaire. Il lance avec succès le javascript et fait l'appel __dopostback. Mais il ne doit pas voir l'ID de contrôle donné ou quelque chose car l'événement ne se déclenche jamais.

using System; 
using System.ComponentModel; 
using System.Drawing.Design; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 

namespace PLSO.Info.Web.UI { 

[DefaultEvent("Submit")] 
[DefaultProperty("Text")] 
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")] 
public class ComboButton : WebControl { 

    private HtmlImage imageControl; 
    private HtmlGenericControl spanControl; 

    private static readonly object EventSubmitKey = new object(); 

    [Bindable(true)] 
    [Category("Appearance")] 
    [DefaultValue("")] 
    [Description("The text to display on the button.")] 
    public string Text { 
     get { return ViewState["NewText"] as string; } 
     set { ViewState["NewText"] = value; } 
    } 

    [DefaultValue("")] 
    [Bindable(true)] 
    [Category("Appearance")] 
    [UrlProperty()] 
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] 
    public string ImageUrl { 
     get { 
      EnsureChildControls(); 
      return this.imageControl.Src; 
     } 
     set { 
      EnsureChildControls(); 
      this.imageControl.Src = value; 
     } 
    } // ImageUrl - Property 

    public override string CssClass { 
     get { return ViewState["CssClass"] as string; } 
     set { ViewState["CssClass"] = value; } 
    } 

    [Category("Action")] 
    [Description("Raised when the user clicks the button.")] 
    public event EventHandler Submit { 
     add { Events.AddHandler(EventSubmitKey, value); } 
     remove { Events.RemoveHandler(EventSubmitKey, value); } 
    } 

    protected virtual void OnSubmit(EventArgs e) { 
     EventHandler SubmitHandler = (EventHandler)Events[EventSubmitKey]; 

     if (SubmitHandler != null) 
      SubmitHandler(this, e); 
    } 

    void ComboButton_Submit(object sender, EventArgs e) { 
     OnSubmit(EventArgs.Empty); 
    } 

    protected override void CreateChildControls() { 
     Controls.Clear(); 

     imageControl = new HtmlImage(); 
     imageControl.Src = this.ImageUrl; 
     imageControl.Alt = this.Text; 
     this.Controls.Add(imageControl); 

     spanControl = new HtmlGenericControl("span"); 
     spanControl.InnerText = this.Text; 
     this.Controls.Add(spanControl); 

     this.Submit += new EventHandler(ComboButton_Submit); 

     ChildControlsCreated = true; 
    } 

    protected override void Render(HtmlTextWriter writer) { 
     PostBackOptions pbo = new PostBackOptions(this); 

     AddAttributesToRender(writer); 
     writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass); 
     writer.AddAttribute("onclick", string.Format("javascript:{0}", Page.ClientScript.GetPostBackEventReference(pbo))); 
     writer.RenderBeginTag(HtmlTextWriterTag.Button); 
     imageControl.RenderControl(writer); 
     spanControl.RenderControl(writer); 
     writer.RenderEndTag(); 
    } 
    } 
} 

Voici mon balisage. J'ai mis dans ce contrôle, puis un ASP: Button. L'événement de ce bouton régulier est touché! Pas le mien.

<ucs:ComboButton ID="btnT4" runat="server" Text="Please" CssClass="PButtonCombo" ImageUrl="~/Styles/icons/edit-find.png" OnSubmit="btnT4_Submit" /> 
<asp:Button ID="btnT5" runat="server" Text="TEST" onclick="btnT5_Click" UseSubmitBehavior="False" /> 

Et voici le rendu HTML:

<button id="MainContent_btnT4" class="PButtonCombo" onclick="javascript:__doPostBack(&#39;ctl00$MainContent$btnT4&#39;,&#39;&#39;)"><img src="../Styles/icons/edit-find.png" alt="Please" /><span>Please</span></button> 
<input type="button" name="ctl00$MainContent$btnT5" value="TEST" onclick="javascript:__doPostBack(&#39;ctl00$MainContent$btnT5&#39;,&#39;&#39;)" id="MainContent_btnT5" /> 

Je dois croire que je suis quelque chose de proche, mais manquant. Été peaufiner pendant des heures aujourd'hui, S'IL VOUS PLAÎT AIDE!

EDIT:

Merci à @ James réponse, tout ce que je ne faisais ajouter ce qui suit au sommet de l'exemple ci-dessus. Il a fait l'affaire mais maintenant il tire deux fois. Pas certain de pourquoi? Voilà donc ma question actuelle:

public class ComboButton : WebControl, IPostBackEventHandler { 

    public void RaisePostBackEvent(string eventArgument) { 
     OnClick(new EventArgs()); 
    } 

    [Category("Action")] 
    [Description("Raised when the user clicks the button.")] 
    public event EventHandler Click; 

    protected virtual void OnClick(EventArgs e) { 
     if (Click != null) 
      Click(this, e); 
    } 

EDIT 2 == SOLUTION

using System.ComponentModel; 
using System.Drawing.Design; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 

namespace PLSO.Info.Web.UI { 

[DefaultEvent("Submit")] 
[DefaultProperty("Text")] 
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")] 
public class ComboButton : Button { 

    private HtmlImage imageControl; 
    private HtmlGenericControl spanControl; 

    [DefaultValue("")] 
    [Bindable(true)] 
    [Category("Appearance")] 
    [UrlProperty()] 
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] 
    public string ImageUrl { 
     get { 
      EnsureChildControls(); 
      return this.imageControl.Src; 
     } 
     set { 
      EnsureChildControls(); 
      this.imageControl.Src = value; 
     } 
    } // ImageUrl - Property 

    protected override void CreateChildControls() { 
     Controls.Clear(); 

     imageControl = new HtmlImage(); 
     imageControl.Src = this.ImageUrl; 
     imageControl.Alt = this.Text; 
     this.Controls.Add(imageControl); 

     spanControl = new HtmlGenericControl("span"); 
     spanControl.InnerText = this.Text; 
     this.Controls.Add(spanControl); 

     ChildControlsCreated = true; 
    } // CreateChildControls - Method - Override 

    protected override void Render(HtmlTextWriter writer) { 
     PostBackOptions pbo = new PostBackOptions(this); 

     AddAttributesToRender(writer); 
     writer.RenderBeginTag(HtmlTextWriterTag.Button); 
     imageControl.RenderControl(writer); 
     spanControl.RenderControl(writer); 
     writer.RenderEndTag(); 
    } // Render - Event - Override 
    } 
} 

Répondre

3

Essayez implémentant l'interface IPostBackEventHandler:

public class ComboButton : WebControl, IPostBackEventHandler 
{ 
    public void RaisePostBackEvent(string eventArgument) 
    { 
     OnSubmit(EventArgs.Empty); 
    } 
} 

Voici un article qui explique la mise en œuvre du IPostBackEventHandler interface:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx

EDIT

Si vos événements sont en quelque sorte en fonction des données, vous devez implémenter l'interface IPostBackDataHandler. Par exemple, vous pouvez utiliser l'interface IPostBackDataHandler pour déclencher l'événement OnTextChanged d'une zone de texte:

public class ComboButton : WebControl, IPostBackDataHandler 
{ 
    public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) 
    { 
     return true; 
    } 

    public virtual void RaisePostDataChangedEvent() 
    { 

    } 
} 

Voici un article qui explique la mise en œuvre de l'interface IPostBackDataHandler:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackdatahandler.aspx

+0

Désolé, je voulais dire 'IPostBackEventHandler' –

+0

Cela l'a fait (MOSTLY) - Maintenant, l'événement se déclenche deux fois. Voyez ma réponse ci-dessous pour que je puisse poster du code. – Grandizer

+0

Vous avez probablement juste besoin de retravailler votre logique de gestionnaire d'événements. De quelle réponse parlez-vous? –

2

Vous devez regarder dans IPostBackEventHandler

Si vous n'exécutez pas cette interface dans votre contrôle, le moteur ASP.net ne transmettra pas les événements à votre contrôle.

+0

+1 Vous méritez aussi un upvote. –

Questions connexes