繁体   English   中英

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

[英]ASP.Net Custom Server Control Not Firing Custom Event

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

我的问题是公开的ServerClick事件(由我相信的NamingContainer)似乎没有触发。 如果我添加任何ASP按钮(“链接”,“图像”或常规按钮)并关联到该Click事件,则将触发它,但是当然,我还有其他呈现的内容。 它可以成功运行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:Button。 该常规按钮的事件被击中! 不是我的。

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

编辑2 ==解决方案

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引擎不会将事件转发到控件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM