【问题标题】:How to generate multiple controls from one control variable如何从一个控制变量生成多个控制
【发布时间】:2017-01-06 23:01:45
【问题描述】:

我正在尝试从一个控制变量创建多个控件(在本例中为面板)。我的意思是当我按下一个按钮时,3 个面板使用一个 Panel 变量出现在不同的位置。我当前的代码是这样的

Panel panel = new Panel();
int panel_LOC = -60;
int i;

private void button1_Click(object sender, EventArgs e)
{
    i = i + 1;
    pane1_LOC = panel_LOC + 60;
    panel.Location = new Point(0, panel_LOC);
    panel.Name = "panelName_" + i.ToString();

    panel.Width = 1052;
    panel.Height = 50;
    panel.BackColor = Color.FromArgb(222, 222, 222);

    panelIWantToCreateTheControlsOn.Controls.Add(panel);
}

当我按下按钮时,它会在位置 0,0 处创建一个具有所需属性的面板。当我第二次按下按钮时,它会在位置 0、60 处创建一个面板,但它会删除第一个面板。当我第三次按下按钮时,它会在位置 0、120 处创建一个面板,然后再次删除面板 2。

这不是我想要的。我希望面板 1 和面板 2 保留而不被删除。如何从一个变量创建多个控件,我可以在每种方法中访问这些控件,并且在创建时不会删除其他控件。

【问题讨论】:

  • 它不会删除第一个面板,它只是将其移动到新位置。请问你想达到什么目的?为什么你认为你必须只使用一个变量来保存对多个 Panel 控件的引用?
  • 我正在制作一个待办事项列表应用程序。您输入您必须执行的操作,然后它会创建一个面板,其中包含在标签内输入的文本。我想使用一个变量,因为所有面板看起来都一样,标签只是包含不同的文本。它可以保存数据,并且可以防止我一遍又一遍地输入相同的变量。
  • 我的评论的意思是当我有这样的代码时: Panel panel1 = new Panel();面板面板 2 = 新面板();等等。这将是有效的,因为它需要我这样做大约 50 次。我不能使用选项卡控件或任何其他控件,因为它们看起来不如平面面板。我知道将来我应该研究自定义控件
  • 通过表单设计器创建一个 panel1 的实例(及其控件,即标签、文本框等)(将其“Modifiers”属性设置为 internal 并将其“Visible”属性设置为 false)。当您需要面板的新实例时,如果它是第一个,请执行“panel1.Visible=true”。否则使用表单的新实例将其面板“移动”到当前表单:“Form1 tempfrm=new Form1() ; tempfrm.panel1.Parent=panel1.Parent ; tempfrm.pane1.Location = ...”。跨度>

标签: c# winforms visual-studio visual-studio-2015


【解决方案1】:

尝试在按钮单击事件中实例化对象。这样每次单击按钮时都会创建一个新对象

Panel panel = new Panel();                        //<<<<<<MOVE THIS LINE
int panel_LOC = -60;
int i;

private void button1_Click(object sender, EventArgs e)
{
    i = i + 1;
    Panel panel = new Panel();                    //<<<<<<TO HERE
    pane1_LOC = panel_LOC + 60;
    panel.Location = new Point(0, panel_LOC);
    panel.Name = "panelName_" + i.ToString();

panel.Width = 1052;
panel.Height = 50;
panel.BackColor = Color.FromArgb(222, 222, 222);

panelIWantToCreateTheControlsOn.Controls.Add(panel);

}

【讨论】:

  • 这意味着我无法在 button1_Click 方法之外访问面板变量
【解决方案2】:

您实际上需要创建一个新面板并使用列表在您的方法之外跟踪它们。

List<Panel> MyPanels = new List<Panel>();
int panel_LOC = -60;

private void button1_Click(object sender, EventArgs e)
{
    Panel panel = new Panel();
    MyPanels.Add(panel);
    panel_LOC = panel_LOC + 60;
    panel.Location = new Point(0, panel_LOC);
    ...

而且您不需要保留变量 i 来计算面板数,因为列表会为您提供计数 MyPanels.Count

【讨论】:

  • 那么我如何访问我的方法之外的变量?
  • 如果是该类中的其他方法,则 MyPanels 是该类的成员,其方法可以引用它。如果您询问如何引用列表中的项目,您将需要学习如何使用列表。你可以去这里:msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx
  • 其实,@Fabio 的回答更好。您已经在 panelIWantToCreateTheControlsOn.Controls 中有一个面板列表。因此,您根本不需要创建自己的列表。如果您需要通过其他方法访问它们,您只需通过它访问它们。如果您需要自己处理它们,列表或字典(如 Fabio 建议的那样)都可以解决问题。
【解决方案3】:

panel 在您的情况下始终引用同一个实例,因此您只需更新现有实例的属性,而不是创建新实例。

因为您已经拥有面板的所有“硬编码”值 - 您只需创建面板的新实例。

要在外部访问Panel 变量,您可以创建用于创建面板的方法

private Panel CreatePanel(string name, int locationY)
{
    var panel = new Panel();

    panel.Location = new Point(0, locationY);
    panel.Name = name;

    panel.Width = 1052;
    panel.Height = 50;
    panel.BackColor = Color.FromArgb(222, 222, 222);       

    return panel;
}

然后在按钮点击中创建面板

int panel_LOC = -60;
int i;

private void button1_Click(object sender, EventArgs e)
{
    i = i + 1;
    var panelName = $"Panel {i}";
    panel_LOC += 60;

    var panel = CreatePanel(panelName, panel_LOC);
    panelIWantToCreateTheControlsOn.Controls.Add(panel);
}

然后您可以在按钮单击之外访问面板

private Panel GetPanelByName(strinig panelName)
{
    return panelIWantToCreateTheControlsOn.Controls
                                          .OfType<Panel>()
                                          .FirstOrDefault(control => control.Name.Equals(panelName));
}

var panel2 = GetPanelByName("Panel 2");
// use panel

或者将所有创建的面板保存到Dictionary&lt;string, Panel&gt; 并从那里访问它们

【讨论】:

  • 这行不通,因为我需要在 button1_Click 方法之外访问面板变量。如果我将变量放在 button1_Click 方法中,我无法在任何其他方法中访问它
  • @unknown 那么你总是可以让它成为类的一个字段吗?
  • @Fabio 说我有你写的前 2 个方法,我有我自己的方法,叫做 MyNewMethod。在 MyNewMethod 中,我想在按下面板时触发该事件时创建一个事件。如何使用此代码执行此操作:this.panel.Click += New System.EventHandler(this.panel1_Click);
  • 您可以将其添加到方法GetPanelByName返回的面板中。
猜你喜欢
  • 2017-03-23
  • 2013-05-21
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多