ASP.Net自定义服务器控件未触发自定义事件



我已经创建了一个自定义服务器控件。它看起来很棒,呈现的HTML也应该如此。我最初有它扩展ControlContainer,现在它扩展WebControl(两者的行为相同。)它有两个属性,ImageUrl和Text。实际上,它将呈现一个通用的HTML标记,其中包含一个和标记。

我的问题是,ServerClick事件是暴露(通过NamingContainer我相信)似乎不火。如果我添加任何ASP按钮(链接,图像或常规),并关联到点击事件,它会触发,但当然我有额外的渲染内容。它成功运行javascript并执行__dopostback调用。但是它不能看到给定的控件ID或其他东西,因为事件永远不会被触发。

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

这是我的标记。我放入这个控件,然后是一个常规的ASP:按钮。常规按钮的事件被击中!不是我的。

<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" />

下面是渲染后的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" />

我必须相信我已经很接近了,只是缺少了一些东西。今天一直在调整它几个小时,请帮助!

编辑:

感谢@James的回答,我所做的只是将以下内容添加到上述示例的顶部。它成功了,但现在发射了两次。不知道为什么?这就是我现在的问题:

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

尝试实现IPostBackEventHandler接口:

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

下面是一篇解释IPostBackEventHandler接口实现的文章:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx

编辑

如果你的事件在某种程度上依赖于数据,你需要实现IPostBackDataHandler接口。例如,您将使用IPostBackDataHandler接口来触发TextBox的OnTextChanged事件:

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

下面是一篇解释IPostBackDataHandler接口实现的文章:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackdatahandler.aspx

你需要查看IPostBackEventHandler

如果你不在控件中实现这个接口,ASP.net引擎不会将事件转发给你的控件。

相关内容

  • 没有找到相关文章