2

I've created a custom WebControl that implements a simple message box that can display at the top of a web page. Similar to how YouTube displays messages on their pages. My problem is passing the Click event from any button I add to the box down to the ASPX page.

Below is the code for the WebControl. I think I have handling the click events right, but when I add this code to my page, the click event never gets called, although Page_Load does.

Here's the code in the APSX page:

<rt:ConfirmationBox ID="ConfirmationBox1" runat="server" BoxType="Info" BoxButtons="OkayCancel" OnOkayClicked="ConfirmationBoxOkayClicked"
    Text="Click OK to close." />

Here's the code in the code behind page:

protected void ConfirmationBoxOkayClicked(object sender, EventArgs e)
{
    ConfirmationBox1.BoxButtons = ConfirmationBoxButtons.None;
    ConfirmationBox1.BoxType = ConfirmationBoxType.Success;
    ConfirmationBox1.Text = "You clicked OK!";
}

Here's the WebControl code:

public enum ConfirmationBoxType
{
    Hidden,
    Success,
    Warn,
    Error,
    Info
}

public enum ConfirmationBoxButtons
{
    None,
    Okay,
    Cancel,
    OkayCancel
}

[DefaultProperty("Text")]
[ToolboxData("<{0}:ConfirmationBox ID=\"ConfirmationBox1\" runat=server></{0}:ConfirmationBox>")]
public class ConfirmationBox : WebControl
{
    private static readonly ILog Log = LogManager.GetLogger(typeof(ConfirmationBox));

    private Button _okayButton;
    private Button _cancelButton;

    public event EventHandler OkayClicked;
    public event EventHandler CancelClicked;

    public virtual void OnOkayClicked(object sender, EventArgs eventArgs)
    {
        if (OkayClicked != null)
            OkayClicked(sender, eventArgs);
    }

    public virtual void OnCancelClicked(object sender, EventArgs eventArgs)
    {
        if (CancelClicked != null)
            CancelClicked(sender, eventArgs);
    }

    protected override void OnPreRender(EventArgs e)
    {
        _okayButton = new Button {ID = "ConfirmBoxOkayButton", CssClass = "button", Text = "OK"};
        _okayButton.Click += new EventHandler(OnOkayClicked);

        _cancelButton = new Button {ID = "ConfirmBoxCancelButton", CssClass = "button", Text = "Cancel"};
        _cancelButton.Click += new EventHandler(OnCancelClicked);
    }

    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Localizable(true)]
    public string Text
    {
        get
        {
            var s = (String)ViewState["Text"];
            return (s ?? String.Empty);
        }

        set
        {
            ViewState["Text"] = value;
        }
    }

    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("Hidden")]
    public ConfirmationBoxType BoxType
    {
        get
        {
            return (ConfirmationBoxType)ViewState["BoxType"];
        }

        set
        {
            ViewState["BoxType"] = value;
        }
    }

    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("None")]
    public ConfirmationBoxButtons BoxButtons
    {
        get
        {
            return (ConfirmationBoxButtons)ViewState["BoxButtons"];
        }

        set
        {
            ViewState["BoxButtons"] = value;
        }
    }

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

    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Id, "alerts");
        base.AddAttributesToRender(writer);
    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        if (Site != null && Site.DesignMode)
        {
            writer.Write("[" + ID + "]");
        }
        else
        {
            if (BoxType == ConfirmationBoxType.Hidden)
                return;

            var theme = HttpContext.Current.Profile["UserTheme"].ToString();

            writer.AddAttribute(HtmlTextWriterAttribute.Id, "confirmBox");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "rt-alert " + RenderBoxType());
            writer.RenderBeginTag(HtmlTextWriterTag.Div);

            writer.AddAttribute(HtmlTextWriterAttribute.Src, string.Format("{0}/{1}/pixel.gif", ResolveUrl("~/App_Themes"), (string.IsNullOrEmpty(theme)) ? "Default" : theme));
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "icon");
            writer.AddAttribute(HtmlTextWriterAttribute.Alt, "Alert icon");
            writer.RenderBeginTag(HtmlTextWriterTag.Img);
            writer.RenderEndTag();

            writer.AddAttribute(HtmlTextWriterAttribute.Class, "rt-alert-content");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            writer.Write(Text);
            writer.RenderEndTag();

            writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "close");
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "$(\"#alerts\").hide()");
            writer.RenderBeginTag(HtmlTextWriterTag.Button);
            writer.Write("close");
            writer.RenderEndTag();

            if (BoxButtons != ConfirmationBoxButtons.None)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, "rt-alert-buttons");
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                if (BoxButtons == ConfirmationBoxButtons.Okay || BoxButtons == ConfirmationBoxButtons.OkayCancel)
                    _okayButton.RenderControl(writer);
                if (BoxButtons == ConfirmationBoxButtons.Cancel || BoxButtons == ConfirmationBoxButtons.OkayCancel)
                    _cancelButton.RenderControl(writer);
                writer.RenderEndTag();
            }

            writer.RenderEndTag();
        }
    }

    private string RenderBoxType()
    {
        switch (BoxType)
        {
            case ConfirmationBoxType.Success:
                return "rt-alert-success";
            case ConfirmationBoxType.Warn:
                return "rt-alert-warn";
            case ConfirmationBoxType.Error:
                return "rt-alert-error";
            case ConfirmationBoxType.Info:
                return "rt-alert-info";
        }

        return string.Empty;
    }
}

1 Answer 1

1

Create a separate method for your custom event handler, like this:

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

Change the name of the button click event and make it protected, like this:

protected void OkayButton_Click(object sender, EventArgs e)
{
     //call your event handler method
     this.OnOkayClicked(EventArgs.Empty);
}

Test this out, and see if it makes a difference.

Sign up to request clarification or add additional context in comments.

8 Comments

Still not working. Should I change the method I'm using to attach the events to the buttons? Right now I'm using the OnPreRender, but I had also tried the OnInit method as well.
Maybe try assigning it OnPreInit?
WebControl doesn't have an OnPreInit. Any other suggestions? Thanks for your help!
I think OnInit is the place to assign it. Have you tried putting it back in OnInit with the changes I suggested?
Figured it out. I needed to use CompositeControl as a base instead of WebControl, and I needed to create the controls in CreateChildControls instead and add them to the Controls list. It works now. Thanks for all your help!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.