Custom Web Control inside another Custom Web Control


Hi
I created a custom web control (CusWebNew) that displays some textboxes by adding them to the ControlCollection of the webcontrol. I also created a custom webcontrol (CustWebButton) that inherts from Button control, and overrided the OnClick function.
When I use CustWebButton on a regular web form, it seems to function correctly.
However, when I added to be part of the ControlCollection of CustWebNew, it stops to work.
Any ideas why?
Thanks
0
m1net
3/5/2007 6:59:47 PM
📁 asp.net.custom-server-controls
📃 3498 articles.
⭐ 0 followers.

💬 10 Replies
👁️‍🗨️ 1578 Views



Hey,
What do you mean by stops to work?  Explain what you are trying to do with it and what it doesn't do.

Brian

"Trust in the Lord and do what is good; dwell in the land and live securely. Take delight in the Lord, and He will give you your heart's desires" (Psalm 37: 3-4).
0
bmains
3/5/2007 7:50:45 PM

I will try.
 I have a web form solution where I have my default.aspx
I created a Web Control Library project within my solution, this is CustWebNew. it has the following code:
     protected override void OnPreRender(EventArgs e)
        {
            TextBox fieldTextBox = new TextBox();
            fieldTextBox.ID = "TXTBOX";
            fieldTextBox.Text = "some text goes here";
            this.Controls.Add(fieldTextBox);
            base.OnPreRender(e);
        }

 
I added another Web Control Library, this is CustWebButton. To test it, I overrided the onclick method to change the displayed text from "preClick" to "postClick".
I drag & drop the CustWebButton to the main solutoin: default.aspx
Run, and press button - works, the displayed text changed.
I removed the CustWebButton from default.aspx.
 
I went to my CustWebNew project, added a reference to CustWebButton dll, then added the following lines to code above
     protected override void OnPreRender(EventArgs e)
        {
            CustWebButton newButton = new CustWebButton;
            TextBox fieldTextBox = new TextBox();
            fieldTextBox.ID = "TXTBOX";
            fieldTextBox.Text = "some text goes here";
            this.Controls.Add(fieldTextBox);
           this.Controls.Add(newButton);
            base.OnPreRender(e);
        }
I then drag and drop CustWebNew to my default.aspx; both textbox & button appear now on the screen, but pressing the button does not change the displayed text of the button.
 
I hope I explained clearly....
Thank You
0
m1net
3/5/2007 8:57:29 PM

Hey,
Yes, sure, but you don't tap into the click event...  You can do that by adding (after you add the button to the controls collection):
newButton.Click += new EventHandler(newButton_Click);
And adding:
void newButton_Click(object sender, EventArgs e)
{
    TextBox box = this.FindControl("TXTBOX") as TextBox;
    if (box != null)
        box.Text = "post click";
}
Also, I wouldn't recommend using OnPreRender to add controls, but would use create a class from the CompositeControl class, and override CreateChildControls instead, and create your class there.

Brian

"Trust in the Lord and do what is good; dwell in the land and live securely. Take delight in the Lord, and He will give you your heart's desires" (Psalm 37: 3-4).
0
bmains
3/6/2007 3:27:58 PM
BMains is right... but also note that adding the eventhandler at prerender is too late (which is why he said to move the location of this code in general) for a click event.  Page_Load() is pretty much the last stop for the event train.  If you want to get onboard, you need to do it before then.

Does your team use the VSIP toolkit or maybe have the bulk of your app factored down to patterns and generators?  Do you need in-house controls that will make your current vendors blush?  If so, we need to talk.
0
Jonathan
3/6/2007 7:26:04 PM

Thanks for the reply bmains
Before I go and create a CompositeControl class, I wanted to make sure that the first solution acutally works.
I tried it, even with a regulare Button and the event doesn't fire...
Am I missing something?
0
m1net
3/6/2007 10:53:09 PM

Hey,
Yes, move the controls to the CreateChildControls collection, because as it was said above, OnPreRender is too late to receive the focus for the event handling (click occurs before OnPreRender).  So, if you move everything to CreateChildControls, it should work.  Your solution will work, so you don't have to worry about spending time on something that won't.  Just, you have to move it to CreateChildControls.

Brian

"Trust in the Lord and do what is good; dwell in the land and live securely. Take delight in the Lord, and He will give you your heart's desires" (Psalm 37: 3-4).
0
bmains
3/7/2007 12:28:54 PM

:( it is not working; this is my code - am I doing correctly?:
namespace HimmaAdvancedForm
{   
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:HimmaAdvancedForm runat=server></{0}:HimmaAdvancedForm>")]
    public class HimmaAdvancedForm : WebControl
    {
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public string Text
        {
            get
            {
                String s = (String)ViewState["Text"];
                return ((s == null) ? String.Empty : s);
            }

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

        [Bindable(true)]
        [Category("HimmaData")]
        [DefaultValue("")]
        [Localizable(true)]
        public string EntityName
        {
            get
            {
                String s = (String)ViewState["EntityName"];
                return ((s == null) ? String.Empty : s);
            }

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

        [Bindable(true)]
        [Category("HimmaData")]
        [DefaultValue("")]
        [Localizable(true)]
        public string Operation
        {
            get
            {
                String s = (String)ViewState["Operation"];
                return ((s == null) ? String.Empty : s);
            }

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

        [Bindable(true)]
        [Category("HimmaData")]
        [DefaultValue("")]
        [Localizable(true)]
        public string OperationSQL
        {
            get
            {
                String s = (String)ViewState["OperationSQL"];
                return ((s == null) ? String.Empty : s);
            }

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

        public void btnNew_Click(object sender, EventArgs e)
        {
            string x;
            x = "1";
        }
    
        protected override void  CreateChildControls()
        {
               base.CreateChildControls();
              // this.Controls.Add(buildWebTable());
               Button btnNew = new Button();
               btnNew.ID = "NEW_RECORD2";
               btnNew.Text = "2" + HttpContext.GetGlobalResourceObject("Resource", "NEW").ToString();
               this.Controls.Add(btnNew);
               btnNew.Click += new EventHandler(btnNew_Click);
        }
    }
}
 
0
m1net
3/7/2007 3:42:24 PM

Got it :)
I was not implementing INamingContainer
 Once I did that, it began to work...
Thank you :D
0
m1net
3/7/2007 3:56:17 PM

Hey,
May I suggest a change, from this:
Button btnNew = new Button();
btnNew.ID = "NEW_RECORD2";
btnNew.Text = "2" + HttpContext.GetGlobalResourceObject("Resource", "NEW").ToString();
this.Controls.Add(btnNew);
to this:
Button btnNew = new Button();
this.Controls.Add(btnNew);
btnNew.ID = "NEW_RECORD2";
btnNew.Text = "2" + HttpContext.GetGlobalResourceObject("Resource", "NEW").ToString();
It may not seem like a lot, but I read on some blogs that you should add the control right after you create it so viewstate can work properly.

Brian

"Trust in the Lord and do what is good; dwell in the land and live securely. Take delight in the Lord, and He will give you your heart's desires" (Psalm 37: 3-4).
0
bmains
3/7/2007 4:48:27 PM

I will do that, thank you :)
 
0
m1net
3/8/2007 1:59:21 PM
Reply: