?
Solved

create button on panel on panel at runtime

Posted on 2005-04-25
23
Medium Priority
?
295 Views
Last Modified: 2010-04-16
Hi Experts!

I would like to create a MainPanel on my form that will be filled with logical units represented by SubPanels which each of them contain a number of control elements like buttons etc.

The number of SubPanels will be by far too much for the MainPanel so I need scrolling function for the MainPanel.

How can I create these SubPanels at runtime in such a way, that automatically the MainPanel appears with horizontal scrollbar, as soon as it is populated with more SubPanels than the screenwidth can display?

How to logically assign the buttons etc. to the subpanels at runtime so that they "know", that they belong to the subpanel and in such a way that the subpanel "knows" that it belongs to the main panel?

I hope you can help me with that. Should not be too difficult for an expert, but it would really help me very much!



0
Comment
Question by:i-Thomas
  • 12
  • 7
  • 4
23 Comments
 
LVL 11

Expert Comment

by:Agarici
ID: 13857579
YourForm.SuspendLayout();

Panel p = new Panel();
Button btn = new Button();
btn.Text = "Button #1";
btn.X = 10;
p.Controls.Add( btn );

btn = new Button();
btn.Text = "Button #2";
btn.X = 100;
p.Controls.Add( btn );

p.X = 20;
p.Y = 20;

YouForm.Controls.Add( p );

YourForm.ResumeLayout();

hth,
A.
0
 
LVL 11

Expert Comment

by:Agarici
ID: 13857593
>> How can I create these SubPanels at runtime in such a way, that automatically the MainPanel appears with horizontal scrollbar, as soon as it is populated with more SubPanels than the screenwidth can display?

set autoscroll to true.
YourForm.AutoScroll = true;


A.
0
 
LVL 21

Expert Comment

by:Yurich
ID: 13862894
a little correction to the above.

as far as i understood you want to have one panel on your form and several subpanels on the main panel

in this case, presuming that you've already added this main panel to your form, substitute YourForm in the code above with MainForm.

Also, you may want to set the size of your main panel,

MainPanel.Size = new System.Drawing.Size( 150, 100 );   // for example

and you can't explicetly change X and Y for your controls, you have to define a new Location, like:

Button b1 = new Button();
b1.Location = new Point( 10, 10 );  // for example

regards
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:Agarici
ID: 13864369
yes, yurich, you are right, ofcourse
however a control has 'Top', 'Left', 'Width' and 'Height' properties and you can use those to move and resize it

hth,
A.
0
 

Author Comment

by:i-Thomas
ID: 13866166
OK, thanks a lot!

I checked and now I have populated my Subpanels (on a MainPanel that I created with the FormsDesigner) with some trackbars, buttons. Scrolling works fine!

How to access these controls, for example how to read the value of trackbar No. 7 ?

I need some kind of datastructure to maintain the SubPanels, because I want to dynamically add / insert / remove them at / from any position...

Thanks again for helping me!
0
 

Author Comment

by:i-Thomas
ID: 13866363
One more remark:

How can I get access to an event in my current arrangement?
0
 
LVL 11

Assisted Solution

by:Agarici
Agarici earned 400 total points
ID: 13866400
>>How can I get access to an event in my current arrangement?

Panel p = new Panel();
p.EventName += new EventHandler( YourEventHandlerMethod );

>>How to access these controls, for example how to read the value of trackbar No. 7 ?

instead of doing

Panel p = new Panel();
YourForm.Controls.Add( p );

p = new Panel()
YourForm.Controls.Add( p );

keep a reference to the new panel into an array:

Panel[] arrPanels = new arrPanel[1001];

arrPanel[i] = new Panel();
//etc.

hth,
A.

0
 
LVL 21

Expert Comment

by:Yurich
ID: 13866850
stacking panels in arrays is good but basically even if you have this kind of hierarchy:

a control on the panel on the panel on the panel on the form

and your control for example is a textbox1,

you can still just access your textbox right anywhere in your code :

textbox1.Text = "something";  // or
this.textbox1.Text = "something"; // no difference

but since you create everything dynamically, events should be handled as described above by Agarici.

A little piece of advice on how to create proper event handlers - for different events they can be different, and may not necessaraly know return type and parameter list for the event-handling function (YourEventHandlerMethod in the example above).

The rule of thumb is events are different but handling of the same event is the same for all controls. Drag & Drop any control on anywhere, set a proper event via properties during design time.  Find out how it's used - first place in the  InitializeComponent() and where is handler crated and use the same for your dynamic handler.

regards

0
 

Author Comment

by:i-Thomas
ID: 13867922
Wow! Thanks again for the good feedback.

As I am a newbee, I did not use Event handlers (at least explicitly created by me).

My understanding is that event handlers pass an event to a function like variables pass values to a function. Is this correct rough and dirty?

I will deal with this stuff tomorrow and dig into it.

Using Arrays should not be a problem, I think.
0
 

Author Comment

by:i-Thomas
ID: 13867997
What about using a collection instead of an array? Does it make sense? Or is this no alternative at all?
0
 
LVL 21

Expert Comment

by:Yurich
ID: 13871080
1. not exactly,
for all controls you have events (mouse click, key down and etc), when you do

control.EventName += new EventHandler( YourEventHandlerMethod );

you're "passing" (os adding, or assigning) a function that will respond (handle the event) to your event, not vice versa.

2. Array is a collectin ;) you don't have to use array as Control[] and I would recommend to use someting like ArrayList since creating array of size 1001 is a bit of a waste if you need to insert only 5 elements. As far as I remember, ArrayList by default is created with 16 elements and then will extend itself automatically. Adding stuff to it is very simple,
ArrayList aList = new ArrayList;
aList.Add( myObject );

getting elements is similar to a standard array, but you have to do casting to your type since it doesn't diffirentiate elements when you add'em - another difference with a standard array:

(( Button )aList[ 0 ]).Text = "Red Button"; // access the first button in the list

regards
0
 

Author Comment

by:i-Thomas
ID: 13874343
Great help! Thanks a lot Yurich!

I wish I could increase points further for you...

I got the ArrayList working for one-level hierarchy, namely my Subpanels.

I have got Button on my SubPanel, how to access this?

What data structure to use here?

Do you recommend that I build an Array List with a struct (if this is possible with objects instead of simple number) or a class?

Let us assume that I have 3 TrackBars on my Subpanel, 2 Buttons, 1 Checkbox, 1 Label and 1 PictureBox.

This is quite a number of different objects. What is the best way to put this object structure combination into my ArrayList?

And how to retrieve values / events for the suggested structure?

0
 

Author Comment

by:i-Thomas
ID: 13892356
Hello Yurich!

I would be very glad, if you could give some additional hint.

If you want, we can open a new thread for this and I will accept this one so far.

OK?
0
 
LVL 21

Expert Comment

by:Yurich
ID: 13892691
1. about your Subpanels.
if you just want to access your button, you have to know the index of it and presuming it's 3 (4th element), it'll be:

(( Button )Subpanels[ 3 ]).Text = "Click Me";

But, you have to have some means for distinguishing your buttons if you have more than one and if you don't keep track of your buttons. The easiest probably would be iterating through the array and checking the names:

for( int i = 0; i < Subpanels.Length; i++ )
{
   if( Subpanel[ i ] is Button ) // first check if it's button at all
   {
       // then you can have switch if you have many buttons or just use if - else if just a few:
      if((( Button )Subpanel[ i ]).Text.Equals( "Click Me" ))
      {
           // do some operation
       }
       else if((( Button )Subpanel[ i ]).Text.Equals( "Push Me" ))
       {
            // do some operaion
       }
       ...
}

2. You shouldn't forget the fact that another way will be declare buttons in the class scope, like:

Button btnClickMe;
Button btnPushMe;
Button btnPressMe; // just somewhere before the constructor

and then dynamically create them on the panels as described above. In this case you just can directly access you buttons (or any control from within your program):

btnClickMe.Text = "Do not Click Me";

I wouldn't recommend to clutter your code with excess of structures and classes as it can get easy hard to maintain.

3. the same will apply for your trackbars and any other control
Events are slightly different since you will have to add them only while creating your items, in the way:

control.EventName += new EventHandler( YourEventHandlerMethod );

specify your function somewhere below and that's it... To get a grasp of how it's all created, Create a button on a form, double click it and check how event hadnler was added to the button and where it was created - then just follow the pattern.

You don't need to retrieve event handlers after they've been added to controls.

regards
0
 

Author Comment

by:i-Thomas
ID: 13943734
Hello Yurich!

  for( int j = 0; j < uxSubPanels.Count; j++ )
            {
                if(uxSubPanels[j] is Button) // first check if it's button at all
                {
                  :


Before asking again I took my time and tried to dig into the whole matter to not ask superflous questions, but:

This does not work!



If I have an ArrayList with Panels in it and each panel has several buttons on it, I cannot iterate through the n buttons per panel with this kind of expression. This never evaluates true. The lines above iterate through the panels, but how to interate through the buttons on each panel?



By the way: SubPanels.Length has to be replaced with SubPanels.Count, if you work with an ArrayList!


I hope we can clarify the misunderstanding!

Best regards,

i-Thomas
0
 

Author Comment

by:i-Thomas
ID: 13943770
Just had another idea:

Would it be a solution to create 1 ArrayList for the panel, 1 ArrayList for trackbar No. 1 on the panel, 1 ArrayList for trackbar No. 2 on the panel etc.?

This sounds somehow strange or not so elegant to me, although it might work, as you wrote that one can access any button, panel etc. directly, even if they have been placed "on" another item.

---

Could it be a solution to create a multi-element panel as a user control? How to access buttons, trackbars in this case?
0
 
LVL 21

Accepted Solution

by:
Yurich earned 1600 total points
ID: 13944588
hello Thomas,

1. sorry about the count

2. that's stange it doesn't work for you, I just created a sample project and it did fine for me :|...

are you positively sure you added controls (in particular buttons) to the ArrayList before running the code?

probably there's a bit of confusion. Subpanel in our code is NOT a panel, it's an ArrayList and to iterate through the controls on each panel, you should use something like:

foreach( Control c in panel1.Controls )
  if( c is Button )
     if( c.Text.Equals( "ClickMe" ))
           // do what you want to do


iteration on all panels on the form just a little bit more complicated:

foreach( Control p in this.Controls )
{
   if( p is Panel )
   {
       foreach( Control c in p.Controls )
       {
             if( c is Button )
             {
                    if( c.Text.Equals( "ClickMe" ))
                    {
                            // your code
                            ...
                    }
              }
          }
      }
}

0
 

Author Comment

by:i-Thomas
ID: 13944680
probably there's a bit of confusion. Subpanel in our code is NOT a panel, it's an ArrayList and to iterate through the controls on each panel, you should use something like:

Yes, exactly there was the confusion and I thought to myself if I should stop programming C#  ;-)


Thanks you very much answering my question anticipating this!

Just for my learning:

Would you create a user control panel with all the buttons, trackbars etc. or would you create them with direct coding?



0
 
LVL 21

Expert Comment

by:Yurich
ID: 13944695
Now about your idea:

1. "Would it be a solution to create 1 ArrayList for the panel, 1 ArrayList for trackbar No. 1 on the panel, 1 ArrayList for trackbar No. 2 on the panel etc.?"

Why would you need to have an ArrayList for each control?

One of the ways that I'm thinking to probably would be creating dynamically your controls, adding them to panels and to appropraite ArrayLists at the same time. That will create a double-hierarchy - you will have different controls on your panels but similar controls would be all collected in your ArrayLists.

2. User controls are fine and I normally use them if I need to swap subforms or subpanels on my main form. Yet it will not be just a bit more complicated.

On one hand, you won't need to create ANY controls at run time but only your user controls. You'll have all of your controls on your user controls created during the design time.

On the other hand, you will have to craete properties for accessing your controls on user controls since there is no simple way as for panels to do it. You will have to create some means as well to interchange some information between your user controls if you need to do it.

To summarize, I'd use user controls only if I wanted to swap'em during run time (show one and hide all others). That would be an alternative for your scrolling - have a few buttons for example and when you press "options 1" you have one panel visible, "options 2" - another one and so on. If you have to have'em all at the same time on the form, in this case you have to stick with the scrolling and using user controls probably not essential.

regards,
Mik
0
 

Author Comment

by:i-Thomas
ID: 13944740
Hi Mik!

Great! Thank you so very much for all your help!

I think I should be equipped with all I need now!

You belong to the guys that make ee so outstanding!!

I would like to split points so that Agarici receives also 100 for initial ideas and participation.

Do you agree?

0
 
LVL 21

Expert Comment

by:Yurich
ID: 13944782
absolutely,
and have a nice weekend - do not program too much ;)
0
 

Author Comment

by:i-Thomas
ID: 13944851
Hi Mik,

at least my Sunday is holy :-)      (... by 95%)

Have a nice weekend, too - and read ya' soon!
0
 

Author Comment

by:i-Thomas
ID: 13945120
I made some experiments with user control and saw that seperate .DLL appears...

Can this be avoided somehow?
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
High user turnover can cause old/redundant user data to consume valuable space. UserResourceCleanup was developed to address this by automatically deleting user folders when the user account is deleted.
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses
Course of the Month16 days, 17 hours left to enroll

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question