具有多个自定义控件的ASP.NET页面,实现IPostBackEventHandler

时间:2012-10-11 05:19:05

标签: asp.net event-handling postback

我有一个ASP.Net页面,其中包含多个实现IPostBackEventHandler接口的控件。代码的简化版本如下:

public partial class WebForm1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Custom Control
        MyTextBox mytxt = new MyTextBox();
        mytxt.ID = "mytxt";
        mytxt.TextChange += mytxt_TextChange;
        this.Form.Controls.Add(mytxt);

        //Custom Control
        MyButton mybtn = new MyButton();
        mybtn.ID = "mybtn";
        mybtn.Click += mybtn_Click;
        this.Form.Controls.Add(mybtn);
    }

    void mybtn_Click(object sender, EventArgs e)
    {
        Response.Write("mybtn_Click");
    }

    void mytxt_TextChange(object sender, EventArgs e)
    {
        Response.Write("mytxt_TextChange");
    }
}

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyTextBox : Control, IPostBackEventHandler
{
    public event EventHandler TextChange;

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

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

    protected override void Render(HtmlTextWriter output)
    {
        output.Write("<input type='text' id='" + ID + "' name='" + ID + "' onchange='__doPostBack(&#39;" + ID + "&#39;,&#39;&#39;)' />");
    }
}

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyButton : Control, IPostBackEventHandler
{
    public event EventHandler Click;

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

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

    protected override void Render(HtmlTextWriter output)
    {
        output.Write("<input type='button' id='" + ID + "' name='" + ID + "' value='Click Me' onclick='__doPostBack(&#39;" + ID + "&#39;,&#39;&#39;)' />");
    }
}

有2个自定义控件 - MyTextBox&amp; MyButton实现了IPostBackEventHandler接口。 MyTextBox具有TextChange事件,MyButton具有Click事件。

如果我只在页面上保留一个控件(MyTextBox或MyButton) - 事件触发属性。但是,如果页面上有这两个控件,即使单击MyButton,MyTextBox TextChange事件也会被触发。当MyTextBox在页面上时,MyButton Click事件不会被触发。

我在此处发布之前尝试了多项内容。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

问题的原因是您需要使用控件的UniqueID调用__doPostBack方法。这很重要。此外,基本上服务器控件将ClientID呈现为元素的ID,将UniqueID呈现为元素名称。因此,如果您将渲染方法更新为以下内容,则一切都将起作用:

文本框:

output.Write("<input type='text' id='" + this.ClientID + "' name='" + this.UniqueID + "' onchange='__doPostBack(&#39;" + this.UniqueID + "&#39;,&#39;&#39;)' />");

按钮:

output.Write("<input type='button' id='" + this.ClientID + "' name='" + this.UniqueID + "' value='Click Me' onclick='__doPostBack(&#39;" + this.UniqueID + "&#39;,&#39;&#39;)' />");

修改

使用UniqueID似乎无助于解决您的问题。我不知道问题的原因,但我尝试使用基本WebControl类覆盖您的自定义文本框,这有助于解决问题。因此,您可以尝试使用此实现。

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyTextBox : WebControl, IPostBackEventHandler
{
    public event EventHandler TextChange;

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

    }

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

    protected override HtmlTextWriterTag TagKey
    {
        get
        {
            return HtmlTextWriterTag.Input;
        }
    }

    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        base.AddAttributesToRender(writer);
        writer.AddAttribute(HtmlTextWriterAttribute.Onchange, Page.ClientScript.GetPostBackEventReference(this, string.Empty));
        writer.AddAttribute("onkeypress", "if (WebForm_TextBoxKeyHandler(event) == false) return false;");
        writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
    }
}