ASP.NET Page with multiple custom controls impleme

2019-07-12 04:38发布

I am having an ASP.Net Page which contains multiple controls which implement the IPostBackEventHandler interface. The SIMPLIFIED VERSION of the code is given below:

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;)' />");
    }
}

There are 2 custom controls - MyTextBox & MyButton implementing the IPostBackEventHandler interface. MyTextBox has the TextChange event and MyButton has the Click event.

If I keep only one control on the page (MyTextBox or MyButton) - the events fire property. But with both controls on the page the MyTextBox TextChange event is getting fired even after clicking the MyButton. The MyButton Click event does not get fired when the MyTextBox is on the page.

I have tried multiple things before posting it here. Thanks in advance for the help.

1条回答
小情绪 Triste *
2楼-- · 2019-07-12 05:07

The cause of the problem is that you need to call __doPostBack method with UniqueID of the control. This is vital. Also, basically server controls render ClientID as ID of the element and UniqueID as element name. So if you update your render methods to the following everything will work:

TextBox:

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

Button:

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

EDIT:

Using UniqueID seems really didn't help to resolve your problem. I don't know the cause of the problem, but I tried to overwrite your custom text box using base WebControl class and this helps to resolve problem. So, you can try to go with this implementation.

[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");
    }
}
查看更多
登录 后发表回答