在运行时添加组合框的问题 [英] problem in adding combobox in runtime

查看:53
本文介绍了在运行时添加组合框的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编程的新手,这是我的代码

  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正在制作一个动态添加到Windows窗体上的组合框,它将组合框一个接一个地放置,我使用面板,以便其他控件不能通过添加运行时控件来实现,这里的问题是当我单击按钮并向面板添加新的组合框时,它成功添加并且我的面板大小为

引用:

260,181

所以当我添加5个组合框时,我必须滚动查看第5个组合框。(滚动面板而不是表格),主要问题仍然存在,当我滚动并且焦点在第5个组合框上,然后当点击按钮添加新的组合框时,新组合框的位置是我之前做过的组合框的位置的两倍,所以它看起来很奇怪,那个五个组合框是按顺序排列的,而第六个是在那个下方较大的距离,如何解决这个问题,请帮助

抱歉我的英文不好

解决方案

首先,我会告诉你我做了什么来理解发生了什么...

我使用System.Diagnostics添加; 到表格然后放入以下

 private void panel1_Scroll(object sender,ScrollEventArgs e)
{
Debug.Print(panel1。 Controls [panel1.Controls.Count - 1] .Location.ToString());
}



当我移动滚动条时,我能够观察到最终组合框的位置正在改变。此外,如果您只是继续添加控件而不滚动到最后一个,那么您不会遇到您描述的问题。它必须与相对位置相关。



所以我在button1_Click
$ b $开头添加了这个b

 panel1.VerticalScroll.Value = VerticalScroll.Minimum; 



问题消失了


唯一我可以复制这个方法是滚动面板 - 这是有道理的,因为坐标是相对于控件的顶部,而不是它的滚动位置的顶部。

尝试包括滚动您所在位置的位置:

 ComboBox txtRun =  new  ComboBox(); 
txtRun.Name = txtDynamic + c ++;
txtRun.Location = new 点( 30 18 +( 30 * c)+ panel1.AutoScrollPosition.Y); ;
panel1.Controls.Add(txtRun);







你能解释一下这将会做什么

panel1.AutoScrollPosition.Y);

i我有点困惑






任何容器上控件的位置都相对于该容器的左上角 - 无论是表单,面板还是拆分器。否则,您在设置位置时必须引用包含控件TLHC,并且在移动容器时必须更新所有控制位置。



面板是一个ScrollableControl的例子(即它来自于香草控制中的相当tna)



当你滚动它时,未滚动位置之间的像素数量差异包含的控件及其相对于容器的TLHC移动的数量将作为AutoScrollPosition提供给您 - 它是容器的TLHC的屏幕位置与逻辑位置之间的偏移量。如果向下滚动五个像素,则AutoScrollPosition的Y坐标变为-5。



向下滚动控件的次数越多,向下移动的值越大相关

所有代码都包括滚动量,以相对于真实TLHC而不是显示的TLHC进行偏移。



为自己尝试一下,它可能会更有意义。处理Panel.Scroll事件并添加以下代码:

  private   void  panel1_Scroll( object  sender,ScrollEventArgs e)
{
Console.WriteLine(panel1.AutoScrollPosition);
}

当你滚动它时,你会看到数字变化,它应该更清晰。





先生,您能告诉我一个与动态验证有关的事吗

如果我使用此代码进行验证


  public   bool  valun()
{
if (combobox.Text == string .Empty)
{
返回 true ;
}
否则
{
返回 false ;
}
}
public void validation_username()
{
bool stat = valun();
if (stat == true
{
label1。 visible = true
}
else
{
label1.visible = true
}
}



那怎么能我验证了我添加的动态控制?





你可以添加一个事件处理程序,并使用sender参数来确定它是哪个组合框。如果你处理离开事件,你可以立即用户出于任何原因退出控件:

 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
{
// ...
}
}





或者你可以按下按钮,并以类似的方式遍历面板控件:

  foreach (控制c   panel1.Controls)
{
ComboBox cb = c as ComboBox;
if (cb!= null
{
// ...
}
}







先生,但第一种验证方法不适用于我的。

i在按钮点击事件中写了这个


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



这个

< pre lang =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的作用:它是条件转换如果正在转换的对象是适当的类型,那么它被强制转换,并且引用被设置到变量中。如果它不是,那么 null 是相反,分配。



因此,如果对象 sender 是ComboBox(或从ComboBox派生的控件),然后将 sender 的引用分配给 cb 。如果不是,则分配null。方法中的测试是确保没有从按钮,DataGridView或其他控件调用该方法。



您的代码将始终分配 false label.Visible 属性,如果处理程序只被添加到ComboBox控件中。你仍然需要检查ComboBox竞赛nt!







并停止向两个不同的控件列表添加控件???

这意味着什么?

我将清除我的问题,让我们从头开始。我正在动态组合框和标签,标签设置为visible = false。就像你做了验证一样,当用户剂量输入enything并离开组合框时,标签设置为true。我只是想这样做,但标签将动态生成,我已经完成了这个




标签label = < span class =code-keyword> new  Label(); 
label.Name = dynamiclabel + c ++;
label.Location = new 点( 160 , - 5 +( 20 * c));
label.Visible = false ;
label.Text = labelname;

ComboBox txtRun3 = new ComboBox();
txtRun3.Name = txtDynamic + c ++;
txtRun3.Location = new 点( 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);



按钮点击事件中的此代码和

  private   void  txtRun_Leave( object  sender,EventArgs e)
{
ComboBox cb = sender as ComboBox;
标签lb =发件人 as 标签;
if (cb!= null
{
if (cb.Text == string .Empty)
{
lb.Visible = true ;

}
else
{
lb.Visible = ;
}
}
}



但错误即将到来

对象引用未设置为对象的实例。



我错了。







停止向两个不同的控件列表添加控件????

这意味着什么?




看看你的代码:

  this  .Controls.Add(txtRun); 
panel1.Controls.Add(txtRun);



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

在这两种情况下,您都将相同的控件添加到两个不同的控件列表中 - this.Controls(表单)和panel1.Controls(面板)。你只想将它添加到面板而不是表格。



我错了。



如果Control是ComboBox,那么它也不可能是一个标签!所以当你执行

 ComboBox cb = sender  as  ComboBox; 
标签lb =发件人 as 标签;

您可以保证两个变量中的一个为空 - 所以当您尝试同时使用两个变量时,您肯定会收到错误。



建议:



您是否知道每个控件都有Tag属性?没有?当你想要关联两个控件时,它真的很方便,因为它可以包含任何对象。如果您将ComboBox的Tag属性设置为相关标签,则可以在Leave事件中准确访问该属性...



标签标签= 标签(); 
label.Name = dynamiclabel + c ++;
label.Location = new 点( 160 , - 5 +( 20 * c));
label.Visible = false ;
label.Text = labelname;

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





  private   void  txtRun_Leave( object  sender,EventArgs e)
{
ComboBox cb = sender as ComboBox;
if (cb!= null
{
Label lb = cb.Tag as 标签;
if (lb!= null
{
.. 。


你的问题是你在设置位置时的问题。 6th Combobox你说的位置显示是



x = 30

y = 18+(30 * 6)= 198



我亲自尝试如下



  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 ;
}





自然你可以调整TopPosition以满足你的需求。


I am newbie to programming, this is my code

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

解决方案

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


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:

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:

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

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:

    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:

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

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


and this

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


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

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:

this.Controls.Add(txtRun);
panel1.Controls.Add(txtRun);

And

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

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...

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;



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)
        {
            ...


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

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.


这篇关于在运行时添加组合框的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆