我在按下按钮时在RunTime中创建的选项卡中引用控件时遇到问题。基本上我所拥有的是一个桌面RPG计算器,使用Windows窗体,它有一个tabControl控制标签页,每个标签页都保存用户输入的统计数据,用于计算个人敌人。
问题在于我希望用户能够单击按钮以生成新的敌人标签页。这是我使用TextBox生成敌人标签页的代码。
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"的TextBox。 + enemyNumber,我不知道怎么做。
我所做的是创造" archVariables"存储选择的任何敌人选项卡中的值,然后在程序的计算中使用适当的archVariable。 IE:archEnemyName。我们的想法是,无论当前选择用户的任何标签(通过SelectedIndex确定),该页面上的TextBox都将用于该程序的输出。
以下是我在研究此事后尝试过的两件事:
// 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;
}
}
这次我得到一个错误:无法转换类型&#39; System.Windows.Forms.Control []&#39;到&#39; System.Windows.Forms.TextBox&#39;
我觉得我在这里的第二种方法可能更接近正确的方法来做到这一点,但显然我还没有做对。我通过搜索stackoverflow和msdn.microsoft上的信息学到了很多东西,但没有任何东西让我解决这个问题。
任何帮助都将不胜感激。
答案 0 :(得分:0)
基本上你的第二次尝试的问题是enemyTab.Controls.Find("enemyNameBox" + i, true)
返回一个控件数组Control[]
而你试图将它转换为控件这里是问题,你应该得到第一个控件该数组然后将其转换为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;
}
}
但这并不是BestWay这样做似乎每次用户添加新的tabPage它会有相同的控件吗?那么为什么不用TabPage上的任何Control创建一个userControl呢?所以当你按下用户按下以添加一个新标签时,你的代码应该是这样的:
private void CreateNewEnemyTab()
{
var newTabPage = new TabPage()
{
Text = "Enemy " + enemyNumber,
};
EnemyTabUserControl enemyTab = new EnemyTabUserControl(enemyNumber);
here the EnemyTabUserControl should have all the components you need;
newTabPage.Controls.Add(enemyTab);
tabControl1.TabPages.Add(newTabPage);
}
以及从当前选项卡中引入TextBox的代码可能如下(您将需要引用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;
答案 1 :(得分:0)
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;
}
}