[C#] User Control: Call a method only once when control is added to a form

Nazgulled

Centurion
Joined
Jun 1, 2004
Messages
119
Hi there,
I'm doing this custom user control but I'm having a little issue. This UC has a ToolStrip added to it and I'm working with control designers which allowed me to create the following:
pagestrip-action-preview.jpg


When you click on "Insert New Page", a method will be called which will create a new button that will be added to the ToolStrip and a Panel will also be added to the UC which will be associated with the the ToolStrip button. So, if we had a bunch of "Pages", whenever you click a button, the Panel associated will turn visible while the others not visible. So far so good?

Now, what I want... Let's say that this UC is almost coded. I compile to a dll file and then I can use it wherever I want. To use it, I just add the dll file to the project and then, drag the UC (which is called PageStrip by the way) from the ToolBox to a form. Now, there's a functionality that I want to be here... When you drag the UC to the form, there won't be any buttons or panels (let's call it "pages" from now on), you'll have to add them manually (like explained in the paragraph above). What I want is a couple of "pages" to be added automatically when the UC is added to the form. Just the way the TabControl works. When you add a TabControl to a form, you'll have 2 tabs already added. How can I achieve the same thing?

How can I call twice the same method that is called on "Insert New Page" one time only, and that is, when the UC is added to the form. I have no clue on how to do that.

My first and only try was overriding the OnPaint event of the UC and call the method there, then, I would assigned the "true" value to a variable so this would only be called once. However, this would only work while the project was opened. If I closed the project and reopened it, the variable that controlled if a "page" was already added would be "false", the default value.

There must be someway to accomplish this without having to workaround like I did using the OnPaint event. Any hints?

I hope this detailed post is enough to explain my problem and not to confuse you.
 
I would love to help you but I've been stumped by this same problem in the past an have never found a solution.
 
Naturally, two minutes after I've made a post saying I don't know the answer, I think I've found it. This solution might be tricky if you aren't at all experienced with coding designers.

Not surprisingly, the TabControl uses a custom designer, System.Windows.Forms.TabControlDesigner, found in System.Design.dll. This designer class overrides the Designer.InitializeNewComponent() method, which is apparently only called the first time a component is added to a form. This is the method where those two initial tab pages are added.

So what you would need to do is create a designer for your control (if you haven't already) by inheriting the System.Windows.Forms.Design.ControlDesigner (the System.Windows.Forms.Design.ParentControlDesigner might be more appropriate, but I'm not sure since I haven't spent much time getting my hands dirty with designers). Specify your designer class as your control's designer using the System.ComponentModel.Designer attribute (if you haven't already). Then override the InitializeNewComponent() method (if you haven't already) and add your default "pages" there.

Just for the record, I haven't tested this.
 
@PlausiblyDamp
Thanks, but that is called every time you open the form. Meaning if you close the tab with the form and reopen it (or close the solution and reopen), it will be called every time.

@marble_eater
Thank you so much, it worked, at least seems to be working... I just don't know the different between ControlDesigner and ParentControlDesigner, but I'm using Parent for now.

So, my code is now like this:
[csharp]private PageStrip pageStrip;

public override void Initialize(IComponent component)
{
base.Initialize(component);

// Record instance of the control we are designing
pageStrip = (PageStrip)component;

// Hook up events
Global.ISS.SelectionChanged += new EventHandler(OnSelectionChanged);
Global.ICCS.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving);
}

public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);

//
Global.AddNewPageStrip(pageStrip);
Global.AddNewPageStrip(pageStrip);
}[/csharp]

And one thing that I never knew when overriding methods is about the "base.SOMETHING" methods. Look at "base.InitializeNewComponent(defaultValues);" and "base.Initialize(component);". Should my code be above or below these lines? And why? I've always placed the code below those code lines but I'm not sure if this is the right way. If you can provide me more insight on this, I wouldn't mind to know more :)
 
I would say that when you override a method and need a call to the base method you would usually add your code after the call to the base method. Your code might depend on initialization done in the base method, even if it isn't initially obvious.
 
the difference between the ControlDesigner and ParentControlDesigner is that the ControlDesigner is used for a userControl or controls that have children that are fixed(label/picBox/...). The ParentControlDesigner is used when your controls need to act as a parent for other controls(panel/groupbox/...)
 
Back
Top