Click here to Skip to main content
15,917,568 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:

I need to create a Array of panel and add in every one of them (panel[i]) an X nombre of controls . Till now no problem, The problem is i need to add to that panel[i] a button that when clicked change the current panel to the panel [i+1]. and i really don't know how to work on it click event .

here is some code to make it more clear

Panel[] panel = new Panel[5];
           int x = 0;

               for (int j = 0; j < 5; j++)
                   panel[j] = new Panel();
          while (x<5){

               panel[x].Visible = true;
               panel[x].AutoScroll = true;
               panel[x].AutoScrollMargin = new Size(30, 30);
               panel[x].Dock = System.Windows.Forms.DockStyle.Fill;
               panel[x].Location = new System.Drawing.Point(0, 0);
               panel[x].Name = "panel" + x;
               MessageBox.Show("Panel :" + panel[x].Name);
               int i;
               for (i = 0; i < 20; i++)
                   Label l1 = new Label();
                   l1.Text = "position " + (i + 1) + "/" + x;
                   l1.Location = new System.Drawing.Point(28, 28 + i * 30);
                   l1.Size = new System.Drawing.Size(80, 13);
                   TextBox t1 = new TextBox();
                   t1.Name = "pos" + (i + 1);
                   t1.Location = new System.Drawing.Point(110, 28 + i * 30);
                   t1.Size = new System.Drawing.Size(80, 13);
               Button b1 = new Button();
               b1.Text= "valider et ajouter";
               b1.Name= "button"+x;
               b1.Location = new Point(269, 28 + i * 30);
               b1.Size = new Size(100, 30);
               int current = x;
              // I need to put the event for the button here but I don't know how

I hope that I making sense .

Please help me , if you have an idea how to solve this issue
Updated 13-Sep-12 1:57am
[no name] 6-Sep-12 11:46am    
You have not added your button to any container. And you have not defined a button click event.
SalouaK 6-Sep-12 12:13pm    
That exactly The problem I don't knwo how i am going to add his click event since there is a X button . but the button is correctly added to the panel[i]

    Salaam Aleikum, SalouaK (hope that's appropriate), and welcome to CP QA.

    This is much too long, and detailed, to be a comment on the OP, but I am going to hold off on giving
    an example of how to accomplish what SalouaK wants to do here efficiently and easily until he shows
    some initiative in responding to my detailed analysis here

    In English, the idiom that is appropriate for this type of "conditionality" for further investment is:
    "putting skin in the game."[^]

Please consider:

0. Based on the code you've shown us here: we can only fantasize what panel1 is, where it's created, what else it may hold before you stick your new run-time created Controls into it..

Is panel1 meant to be the container that you will add all the run-time created Panels to the ControlCollection of: not "this" ?

Occam's Razor suggests that is the most likely answer, and there is a better way to suspend (hint, hint) panel1's run-time appearance while you go about creating all this stuff, if that's really necessary ... like when it's done outside the Form Load EventHandler, arbitrarily, at run-time, in response to some user action in the UI.

1. major flaw: all your run-time created Panels are added to the ControlCollection of 'this by
Okay, 'panel in this case is your variable name for a five-element array of Panels ('panelAry or 'ArrayOfPanels would be much more appropriate choices for this variable name, if you want other people to understand your code in the future). Also see comment #3 below.


    a. remember that when you create your array of Panels: your variable of type Panel[] 'panel, initially, contains 5 null entries.

    b. so every time you execute: Controls.Add(panel[1]: you add a 'null, when the value of 'x == 0: once the value of 'x == 1: when you've actually inserted a new Panel into panel[1]: then:

    c. for each iteration where 'x >= 1, you will be re-adding panel[1] to the ControlsCollection of 'this ! This will not cause a run-time error, but: there will be one, and only one, instance of 'panel[1] added to this' ControlCollection !

    ~ aside: I'd actually like to see Visual Studio throw a run-time error if you re-add the same
    instance of some Control to a ControlCollection, or add a 'null ! ~

Clearly, what you want to do is to add your run-time Panel to the "target" container using the index in your for-loop:
note that if you do, as I suspect, really intend 'panel1 to be the container for all the new run-time created Panels and their Label/TextBox pairs: then you'd want to see something like
2. we can see you add each new run-time created Panel to the ControlCollection of 'this: but if there are other Controls already in the ControlCollection of 'this: then the Index property of your run-time created Panels in that ControlCollection is going to be determined by how many other Controls are in it: is that going to create a problem for you later:

If you do, as I suspect, intend for 'panel1 to be the container for all the new run-time created Panels, and their Label/TextBox pairs: then that's not an issue as long as 'panel1 has no other Controls in it..

3. most confusing of all: you set the Visible property of the Panel, 'panel1, to 'false every time you execute the for-loop. You only to make it not visible once :)

4. you are using fixed values here both for the number of Panels created, and then the number of Label/TextBox "pairs" added into each Panel created: don't you really want to make your code more flexible by using variables to contain the numbers of Panels, and Label/TextBox pairs ?

Well, okay, maybe it will always be 5 Panels and 20 Label/TextBoxes: no problem :)

5. because you set the Dock property to 'DockStyle.Fill, all Panels created at run-time, and that you add to whatever container's ControlCollection will appear "on top" of each other in their container Control, so "navigating" from Panel to Panel may require slight differences in code:

remember: as you add Controls to a ControlCollection, and set 'Dock = 'DockStyle.Fill: the first added will appear on top; the last added is at the bottom (default order is first to last): if you want the last added to appear on top, and the first on the bottom (last to first order): use 'BringToFront after you add the Control.

If do not want continuous navigation in-order from Panel to Panel, and are choosing which one to put on top based on some user action: this is irrelevant.


Now: how to do this much more easily: as soon as you, SalouaK, give some clear response to the questions I've asked here, and the issues I've pointed out in your code:

I'll be happy to help you further.

best, Bill
Share this answer
AmitGajjar 10-Sep-12 0:06am    
SalouaK 13-Sep-12 6:44am    
Salam Bill, (it's Miss and Not a Mr :p)

I am sorry that I'm bet late, but i've been taken back by other projects ,
For your question here is my answers:
1)I've alredy detected that flaws and immediatly corrected and I am sorry i dodn't post my last Code, i should have done it before now.

2)this.Controls.Add(panel[x]); I didn't mean it as the panel1 is the container but the form itself. (I was using panel1 as test before and i forgot to deleted it from my program, please forgave my neglect)

3)I remove it , i should have put it before the loop. again neglect (I should have took some more coffee that day).

4) Iam just using it for the exemple so people will have a concrete idea about what i want to do.

5) Note taken .

I am really sorry for my poor english ,English is not my first langage neither my second.
and Thanks lot for your time and intrest. I hope you still want to help me because i really need some guidanceand very soon .
BillWoodruff 13-Sep-12 7:26am    
Hi, SalouaK,

It is always a good idea to test your code by setting break-points in the code; in Visual Studio for example, in this case: I'd set a break-point on the first statement inside the 'for loop: then use the F11 key (or equivalent in your language's keyboard) to single step through the loop: at each statement, as you single-step, hover your mouse over variable names in the source code, and you can quickly see what their actual content is using the pop-up Visual Studio provides.

I also strongly encourage you to not put your run-time generated controls into the Form itself because of the issue that you may not know how many other controls are in the Form, and, so, when you try to get to one of your run-time generated panels, it may not have the index you think it has.

In general folks here (including me) who answer questions are not going to respond to code that has so many obvious errors.

If you carefully study all the comments on this thread, I think you have all the "raw materials" you need to easily figure out how to move from panel to panel, and if you reach the last panel, how to move back to the first.

Hint: look at Super Lloyd's response to you which uses the modulo operator "%" in the same way I do to navigate in a "circular way."

I think you need to get a good book on C# and WinForm basics and study it, and get familiar with all the resources Visual Studio offers for debugging.

Even though the book is now six-years old, I think Matthew McDonald's "Pro .NET 2.0 Windows Forms and Custom Controls in C#"

Is still the best book I've seen for clearly presenting the essentials of .NET C# programming and controls. He's a very, very good writer !

good luck, Bill

To achieve your solution two things you need to do, First is to create Button control and add it in your particular Panel. Secondly you need to create button click event for each and every button. In click event you need to get that control and remove it from the panel that it belongs and Add in the immediate next panel in your form.
yourButton.Click += new EventHandler(yourButton_Click);

private void yourButton_Click(Object sender, EventArgs e)
// Here sender is your button control. 
// Remove Controls from (i)th Panel.
// Add Button control in (i+1)th Panel.
Panel[i+1].Controls.Add(sender as Button);

Hope it will work for you,
-Amit Gajjar
Share this answer
BillWoodruff 6-Sep-12 13:14pm    
There are fundamental flaws in code which I discuss below: until those are corrected this discussion is premature: but:

I think you are a little off track here: yes the OP needs to add the Button ... the one already created named 'b1 ... to each Panel's ControlCollection. And, yes, the OP needs to add an EventHandler, like Click, or MouseClick to 'b1.

However, the idea to Remove the Button from the current Panel's ControlCollection, and then Add it to the next Panel's ControlCollection: is ... well ... let's euphemize it: "over-engineering:" it also ignores that the desired result of the Button getting a click is to shift focus to the next Panel. Buttons are "cheap:" there is no need to move one Button from one Panel to another, and it would be a pain the ass to do so: you'd have to re-position it every time you moved it, etc.

best, Bill
AmitGajjar 7-Sep-12 0:22am    
ok i understand it. repositioning button is really pain. but OP have such requirement. so i have just given him an idea.
BillWoodruff 7-Sep-12 6:09am    
Namaste, Amit Gajjar, I cannot see how you can, from the OP's description as it is now, conclude that one movable button that "travels" from panel-in-array to next panel-in-array is a "requirement." But, you may be more "psychic" than I am ! (Hindi: "manasika" ?)

best, Bill
AmitGajjar 7-Sep-12 6:33am    
ok, Let's leave this topic here and move ahead. As OP already got his answer :)
BillWoodruff 7-Sep-12 23:10pm    
Namaste, Amit, I've already left this topic "behind:" until SalouaK comes back with some response :)

But, please, tell me where on this thread the OP "got an answer:" I can't see it.

The original code is still unchanged: and it still contains the flaw that the Array of Panels will contain: [null, panel1, panel1, panel1, panel1].

See my comments on Super Lloyd's solution for why it is way off-base.

Evidently no one on this thread, but me, has actually tested a solution in code: it was easy for me to do because I've implemented this kind of navigate between Panels thing many times: a key difference that I usually create only two buttons, in a container that holds all the Panels (like another Panel) for forward, and back, and then make them effectively "loop:" so if you are at the "last Panel" and click the "Forward Button," you return to the "first Panel," and the reverse.

best, Bill
Use lambda expressions / anonymous method to add inline event handler.

Don't forget to capture current value of relevant variable (as lambda capture variable and not value, i.e. if it captures 'x' it will be 5 when the button is clicked)

example (to add below the button creation)
int current = x; // WARNING: don't use x! You have been warned!
b1.Click += delegate {
  for (int i=0; i<panels.length;>  panel[(current+1)%panel.Length].Visible = true;
Share this answer
BillWoodruff 8-Sep-12 7:09am    
Edited for more clarity, and an exact explanation of why the code posted by Super LLoyd here will not compile:

Sorry, but I still have to vote this a #1:

0. you have, obviously, not tested this, and it's full of errors: small and large:

a. you now use a variable name in your code, 'panels, that is never declared in the OP's code, and that you never declare: fail.

b. You use: i<panels.length;> in your for loop:

1. ".length" instead of ".Length" : fail.

2. there's a close angle-bracket here that is an obvious mistake: fail.

3. your for loop is not terminated properly with the variable incremented, and a close parens: fail.

4. you do not bracket the code to be executed in the 'for loop in curly braces: fail.

5. the delegate is not terminated with a semi-colon: fail.

6. I see you using a delegate with anonymous method here, which is, certainly, one valid alternative, and you mention lambda notation, but I see no evidence of your using lambda here: ?

Bigger issues:

1. the OP is obviously at a very beginning level with C# and WinForms: his code, as is, is fundamentally broken: his Array of Panels will contain: [null, panel1, panel1, panel1, panel1] ... and then, there is the mysterious undeclared, and unused, variable, 'panel1, that the OP's code makes invisible every time through the loop ! Please see my "attempt at an education partial-solution" below for my guess on what the OP intended 'panel1 to be used for.

2. introducing to someone, at such a beginning level, and so confused, the concept of delegates with anonymous methods, and lambda notation, and the associated issue of internal variable "capture:" is way too advanced a concept: and it's over-engineering in this case, anyway.

3. your code here adds a Button Click EventHandler to each Button in each Panel that will set the panel[current + 1] ... modulo the length of the panel[] array: so its 'Visible property is 'true. Nice idea to use 'modulo to make going from last Panel to first Panel "automatic" !

But, the OP's code has never hidden any of the Panels in panel[0~4] !

4. since the code shown in the OP's code does not position, or size, the run-time created Panels: they're all going to be in the same place, i.e., overlapping: so the task of the Button Click is going to be to move to the next Panel by using 'BringToFront ... unless, of course, there's code we were not shown here by the OP that positions the Panels so they do not over-lap: in that case the task would be for the Button Click to make the next Panel have 'Focus.

Lloyd, for someone with a 17k+ Code Project rep, I expect better than this from you if you are to retain your "Super" :)

your meddling grandfather, Bill

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900