Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I am newbie to programming, this is my code
C#
int c = 0;

       private void button1_Click_1(object sender, EventArgs e)
       {
   ComboBox txtRun = new ComboBox();
   txtRun.Name = "txtDynamic" + c++;
   txtRun.Location = new System.Drawing.Point(30, 18+(30*c));
   this.Controls.Add(txtRun);
   panel1.Controls.Add(txtRun);
   }


i am making a combobox which is added dynamically on a windows form, it places the combobox one after the other, and i used panel so that the other control cannot be effected by the adding of runtime control, here the problem is when i click the button and add new combobox to the panel, it adds successfully and my panel size is
Quote:
260, 181
so when i add 5 combobox then i have to scroll to see the 5th combobox.(scroll the panel not the form), and the main problem persist here, when i scroll and the focus is on 5th combobox and then when click on button for adding new combobox then the location of the new combobox is double the location of combobox which i have made earlier so, it looks odd, that five of combobox are in sequence and the 6th one is at the larger distance below that, how to solve this problem, plz help
sorry for my bad english
Posted
Updated 10-Dec-12 3:13am
v2
Comments
sariqkhan 10-Dec-12 9:12am    
+5
shaikh-adil 10-Dec-12 9:14am    
thanks bro.

Firstly I'll show you what I did to understand what was going on ...
I added using System.Diagnostics; to the form and then put in the following
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
	Debug.Print(panel1.Controls[panel1.Controls.Count - 1].Location.ToString());
}

I was then able to observe that the location of the final combo box was "changing" as I moved the scrollbar. Also if you just keep adding controls without scrolling to the last one then you don't get the problem you describe. It must be to do with relative locations then.

So I then added this at the start of button1_Click
panel1.VerticalScroll.Value = VerticalScroll.Minimum;

and the problem went away
 
Share this answer
 
v2
Comments
shaikh-adil 10-Dec-12 10:41am    
+5 thanks to you also sir.
:)
shaikh-adil 10-Dec-12 10:44am    
panel1.VerticalScroll.Value = VerticalScroll.Minimum;
what does this means sir?
it is adding the vertical scroll value which is minimum?? what is this?
CHill60 10-Dec-12 11:10am    
I could have probably used "panel1.VerticalScroll.Value = 0;" but using VerticalScroll.Minimum is better ... basically it means "scroll right to the top of this panel control before adding another combobox". See also Griff's comments below
shaikh-adil 10-Dec-12 11:33am    
:)got you.
thanks for explaning and if i want to implement your method and if i want to focus on the last combobox then what can i do?
CHill60 10-Dec-12 12:11pm    
You could use "panel1.Controls[panel1.Controls.Count - 1].Focus();".
Note however, I thoroughly recommend OriginalGriff's approach in preference to mine
The only way I could duplicate this was to scroll the panel - which makes sense, because the coordinates are relative to the top of the control, not the top of it's scrolled position.
Try including the scroll position in your location:
C#
ComboBox txtRun = new ComboBox();
txtRun.Name = "txtDynamic" + c++;
txtRun.Location = new Point(30, 18 + (30 * c) + panel1.AutoScrollPosition.Y); ;
panel1.Controls.Add(txtRun);



"can you explain sir what this will do
panel1.AutoScrollPosition.Y);
i am confused a little bit"



The Location of a control on any container is relative to the top left hand corner of that container - be it a form, or a panel, or a splitter. Otherwise it you would have to refer to the containing control TLHC when you set position, and all control locations would have to be updated when you moved the container.

A panel is an example of a ScrollableControl (i.e. it derives from that rather tna from the vanilla Control)

When you scroll it, the amount of pixels difference between the unscrolled position of a contained control and the amount it has moved relative to the TLHC of the container is given to you as the AutoScrollPosition - it is the offset between the on-screen position of the TLHC of the container, and the logical position. If you scroll it five pixels down, the Y coordinate of the AutoScrollPosition goes to -5.

The more you scroll the control down, the move negative the value in the relevant
All the code does is include the amount of the scroll, to make the offset relative to the real TLHC rather than the displayed TLHC.

Try it for yourself, and it will probably make more sense. Handle the Panel.Scroll event and add the following code:
C#
private void panel1_Scroll(object sender, ScrollEventArgs e)
    {
    Console.WriteLine(panel1.AutoScrollPosition);
    }
As you scroll it, you will see the number change, and it should be clearer.


"sir can you tell me one more thing relating to dynamic validation
if i am using this code for validation

C#
public bool valun()
        {
            if (combobox.Text == string.Empty)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
public void validation_username()
        {
            bool stat = valun();
            if (stat == true)
            {
		label1.visible =true 
            }
            else
            {
               label1.visible =true 
            }
        }

then how can i validate dynamic controlwhich i have added?"


You could add an event handler, and use the sender parameter to identify which comboBox it was. If you handle the Leave Event you can do it immediately the user exits the control for any reason:
C#
    txtRun.Leave += new EventHandler(txtRun_Leave);
    panel1.Controls.Add(txtRun);
    }
...
private void txtRun_Leave(object sender, EventArgs e)
    {
    ComboBox cb = sender as ComboBox;
    if (cb != null)
        {
        //...
        }
    }


Or you can do it on a button press, and iterate through the panels Controls in a similar way:
C#
foreach (Control c in panel1.Controls)
    {
    ComboBox cb = c as ComboBox;
    if (cb != null)
        {
        //...
        }
    }



"sir but the first method of validation is not working in mine.
i have written this in the button click event

C#
txtRun.Leave += new EventHandler(txtRun_Leave);
            panel1.Controls.Add(txtRun);

and this
C#
private void txtRun_Leave(object sender, EventArgs e)
        {
            ComboBox cb = sender as ComboBox;
            if (cb != null)
            {
                label1.Visible = false;
            }
            else
            {
                label1.Visible = true;
            }
        }

as outside.. whats the problem there is no error coming"


No, no, no...
You need to learn what "as" does: it is a conditional cast operator. If the object being cast is of the appropriate type, then it is cast, and the reference is set into the variable. If it isn't, then null is assigned instead.

So, if the object sender is a ComboBox (or a control derived from ComboBox), then the reference to sender is assigned to cb. If it isn't, then null is assigned. The first test in the method is to make sure that the method has not been called from a button, or a DataGridView, or some other control.

Your code will always assign false to the label.Visible property if the handler is only ever added to a ComboBox control. You still need to check the ComboBox content!



"And stop adding controls to two different Controls lists ???
what does this means?
and i will clear my problem, lets start from start. i am making a combobox and label dynamically, label is set to visible = false. and just as same what you have done validation, when user dosent enter enything and leaves the combobox then the label is set to true. i just want to do that but the label will be dynamically generated, i have done this


C#
Label label = new Label();
      label.Name = "dynamiclabel" + c++;
      label.Location = new Point(160, -5 + (20 * c));
     label.Visible = false;
     label.Text = "labelname";

      ComboBox txtRun3 = new ComboBox();
      txtRun3.Name = "txtDynamic" + c++;
      txtRun3.Location = new Point(30, 18 + (20 * c));


      this.Controls.Add(txtRun3);
      this.Controls.Add(label);
      txtRun3.Leave += new EventHandler(txtRun_Leave);

      panel1.Controls.Add(label);
      panel1.Controls.Add(txtRun3);

this code in the button click event and
C#
private void txtRun_Leave(object sender, EventArgs e)
      {
          ComboBox cb = sender as ComboBox;
          Label lb = sender as Label;
          if (cb != null)
          {
              if (cb.Text == string.Empty)
              {
                  lb.Visible = true;

              }
              else
              {
                  lb.Visible = false;
              }
          }
      }

but the error which is coming is this
"Object reference not set to an instance of an object."

where i am wrong."



"stop adding controls to two different Controls lists ???
what does this means?"


Look at your code:
C#
this.Controls.Add(txtRun);
panel1.Controls.Add(txtRun);
And
C#
this.Controls.Add(label);
panel1.Controls.Add(label);
In both cases you are adding the same control to two different Controls Lists - this.Controls (the form) and panel1.Controls (the panel). You only want to add it to the panel, not the form.

"where i am wrong."

If a Control is a ComboBox, then it can't also be a Label! So when you execute
C#
ComboBox cb = sender as ComboBox;
Label lb = sender as Label;
You are guaranteed that one of the two variables will be null - so when you try to use both, you are certain to get the error.

A suggestion:

Did you know that every control has a Tag property? No? It's really handy when you want to relate two controls, because it can contain any object. If you set the Tag property of the ComboBox to the relevant Label, you could access exactly that one in your Leave event...

C#
Label label = new Label();
label.Name = "dynamiclabel" + c++;
label.Location = new Point(160, -5 + (20 * c));
label.Visible = false;
label.Text = "labelname";

ComboBox txtRun3 = new ComboBox();
txtRun3.Name = "txtDynamic" + c++;
txtRun3.Location = new Point(30, 18 + (20 * c));
txtRun3.Tag = label;


C#
private void txtRun_Leave(object sender, EventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if (cb != null)
    {
        Label lb = cb.Tag as Label;
        if (lb != null)
        {
            ...
 
Share this answer
 
v5
Comments
CHill60 10-Dec-12 10:35am    
Far better solution than mine! +5
shaikh-adil 10-Dec-12 10:40am    
+5:)
thanks sir
shaikh-adil 10-Dec-12 10:43am    
can you explain sir what this will do
panel1.AutoScrollPosition.Y);
i am confused a little bit
OriginalGriff 10-Dec-12 10:55am    
Answer updated
shaikh-adil 10-Dec-12 11:27am    
thank you sir
:)
very thanks for helping us
your problem is where you are setting the location as when you hit the 6th Combobox you are saying that the location show be

x = 30
y = 18+(30*6) = 198

personally I would attempt it as follows

C#
private int ComboTopPosition = 20;
private int ComboNumber = 0;

private void button1_Click_1(object sender, EventArgs e)
{
  ComboBox txtRun = new ComboBox();
  txtRun.Name = "txtDynamic" + ComboNumber.ToString();
  txtRun.Location = new System.Drawing.Point(30, ComboTopPosition);
  panel1.Controls.Add(txtRun);

  ComboTopPosition += 30;
  ComboNumber += 1;
}


naturally you can adjust the TopPosition to suit your needs.
 
Share this answer
 
Comments
CHill60 10-Dec-12 10:34am    
I can get the same problem as the poster if I try this
Simon_Whale 10-Dec-12 10:44am    
Thanks learnt something new :D

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