C# 在新选项卡页中引用动态创建的控件
经过数小时的搜索,这里的新手程序员让我感到困惑 在运行时按按钮创建的选项卡中引用控件时遇到问题。基本上,我有一个桌面RPG计算器,使用Windows窗体,它有一个tabControl保存tab页,每个tab页保存用户输入的用于计算的单个敌人的统计数据 问题是,我希望用户能够单击一个按钮来生成一个新的敌人标签页。这是我用文本框生成敌人标签页的代码C# 在新选项卡页中引用动态创建的控件,c#,winforms,C#,Winforms,经过数小时的搜索,这里的新手程序员让我感到困惑 在运行时按按钮创建的选项卡中引用控件时遇到问题。基本上,我有一个桌面RPG计算器,使用Windows窗体,它有一个tabControl保存tab页,每个tab页保存用户输入的用于计算的单个敌人的统计数据 问题是,我希望用户能够单击一个按钮来生成一个新的敌人标签页。这是我用文本框生成敌人标签页的代码 int enemyNumber = 0; // Creates a new Enemy Tab private void bu
int enemyNumber = 0;
// Creates a new Enemy Tab
private void button2_Click_1(object sender, EventArgs e)
{
// Create a new TabPage
var newTabPage = new TabPage()
{
Text = "Enemy " + enemyNumber,
};
// Add Enemy Name Box
var newEnemyNameBox = new TextBox()
{
Name = "enemyNameBox" + enemyNumber,
Text = "",
Location = new Point(127, 11),
Size = new Size(133, 20)
};
// Add the controls to the new Enemy tab
newTabPage.Controls.Add(newEnemyNameBox);
// Add the TabPage to the TabControl
tabControl1.TabPages.Add(newTabPage);
// Increases the enemy's "reference number" by 1
// So that enemy tabs will be generated in order enemyTab0, enemyTab1, etc.
enemyNumber += 1;
}
这一切都很好。不幸的是,在这一点之后,事情变得很糟糕。我需要引用名为enemyNameBox+enemyNumber的文本框,但我不知道该怎么做
我所做的是创建archVariables来存储选择的任何敌人选项卡中的值,然后在程序的计算中使用适当的archVariable。艾:阿奇尼玛名字。其思想是,无论用户当前在哪个选项卡上被选中,都将通过SelectedIndex确定该页面的文本框用于程序的输出
以下是我在调查此事后尝试过的两件事:
// Attempt 1
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
archEnemyNameBox = ((TextBox)Controls["enemyNameBox" + i]).Text;
}
}
当我按下按钮时,这段代码只是抛出一个NullReferenceException。因此,在研究了更多之后,我尝试了以下方法:
// Attempt 2
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
TextBox tb2 = new TextBox();
tb2 = ((TextBox)(enemyTab.Controls.Find("enemyNameBox" + i, true)));
archEnemyNameBox = tb2.Text;
}
}
这次我遇到一个错误:无法将类型“System.Windows.Forms.Control[]”转换为“System.Windows.Forms.TextBox”
我觉得我在这里使用的第二种方法可能更接近于正确的方法,但显然我仍然没有做到这一点。通过搜索stackoverflow和msdn.microsoft上的信息,我学到了很多东西,但没有任何东西让我克服这个问题
任何帮助都将不胜感激。基本上,第二次尝试的问题是enemyTab.Controls.FindenemyNameBox+i,true返回控件数组Control[],您正试图将其转换为控件,这就是问题所在,您应该获取该数组中的第一个控件,然后将其转换为控件,因此应如下所示:
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
TextBox tb2 = new TextBox();
tb2 = ((TextBox)(enemyTab.Controls.Find("enemyNameBox" + i, true)[0]));
archEnemyNameBox = tb2.Text;
}
}
从当前选项卡中获取文本框的代码如下,您需要引用LINQ
using System.Linq;
//First Lets create this property, it should return the selected EnemyTabUserControl inside the tabControl
public EnemyTabUserControl CurrentTab {
get {
return tabControl1.SelectedTab.Controls.OfType<EnemyTabUserControl>().First();
}
}
// then if we make the textbox you want to reference from outside the code we can do this
CurrentTab.NameOfTheTextBox;
帕特里克已经解决了你的基本问题,但我认为你根本不需要这个循环。在这里,我已将步骤分解,以便您可以看到需要更好地进行的操作:
private void defendCalcButton_Click(object sender, EventArgs e)
{
Control[] matches = this.Controls.Find("enemyNameBox" + tabControl1.SelectedIndex.ToString(), true);
if (matches.Length > 0 && matches[0] is TextBox)
{
TextBox tb = (TextBox)matches[0];
archEnemyNameBox = tb.Text;
}
}
非常感谢!你建议的解决方案确实更容易处理,而且效果很好,这正是我所需要的。也许更重要的是,我从中学到了一些新东西。干杯
private void defendCalcButton_Click(object sender, EventArgs e)
{
Control[] matches = this.Controls.Find("enemyNameBox" + tabControl1.SelectedIndex.ToString(), true);
if (matches.Length > 0 && matches[0] is TextBox)
{
TextBox tb = (TextBox)matches[0];
archEnemyNameBox = tb.Text;
}
}