昨天晚上回寢室看到室友正在被一個C#課的作業苦惱,作業的內容是編寫一個口算訓練程序,能夠實現隨意添加題目數量。於是,喜歡寫C#的我就決定解救一下他們。
既然要動態添加,那就必須使用動態控件了。在C#中,控件也是類,除了在畫窗體的時候添加固定的控件外,還可以在代碼中用實例化類的方法添加。
具體操作是,我們先定義一個控件變量,然後對控件設置Size, Location這些屬性,最後,再把控件添加的一個panel中。而且我們只要定義一次控件變量,之後用new不停的添加,就可以獲得很多控件了。
部分代碼如下
txtBox = new TextBox(); txtBox.Size = new Size(50, 50); //設置大小 txtBox.Location = new Point(x, y); //設置位置坐標 txtBox.Name = "txt" + Convert.ToString(i); //設置控件名(可重名) panelQuestion.Controls.Add(txtBox);
在窗體中手動繪制的控件,我們可以通過控件名直接訪問,但是動態添加的控件就不可以了,只能在panel中查找對應Name屬性的控件。
string str = ((TextBox)panelQuestion.Controls.Find("txtBox" ,true)[0]).Text;
Find方法中的第一個參數為控件名稱,第二個參數為是否搜索所以子控件。由於可以重名,所以返回的是一個控件數組,上面的[0]表示取第一個返回結果。由於返回的類型是Control,還需要強制轉換為具體的控件類型,所以前面加了(TextBox),強制轉換為TextBox類型,這樣才能當做TextBox使用。

窗體設計如上圖,控件名稱分別為txtTotal, btnAdd, btnJudge, panelQuestion
在出題按鈕事件中,進行進行動態添加TextBox和Label,每行3個TextBox,顯示兩個加數和一個空白框填寫結果,Name都為txt+行號;還有三個label,從左到右為“+”、“=”和空白的用來顯示對錯。
在批改按鈕事件中,訪問已經動態建立的控件,獲取TextBox裡的值,然後進行批改,把對錯寫入每行最後一個Label中。
運行結果如下:

其他的不廢話了,貼代碼!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace AddProgram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
if (txtTotal.Text == "")
{
MessageBox.Show("請輸入題目數!", "錯誤");
return;
} //判斷題目數是否未填
panelQuestion.AutoScroll = true; //為panel添加滾動條
panelQuestion.Controls.Clear(); //清空已有題目
int total = int.Parse(txtTotal.Text); //題目總數
TextBox txtBox = new TextBox();
Label label = new Label();
Random rand = new Random(); //隨機數
for (int i = 0; i < total; i++)
{
for(int j = 0; j < 3; j++)
{
txtBox = new TextBox();
txtBox.Size = new Size(50, 50); //textbox大小
txtBox.Location = new Point(10 + 70 * j, 30 * i); //textbox坐標
txtBox.Name = "txt" + Convert.ToString(i); //設定控件名稱
if (j < 2)
{
txtBox.Text = Convert.ToString(rand.Next(100));
txtBox.ReadOnly = true;
} //產生隨機數,作為加數
panelQuestion.Controls.Add(txtBox); //把控件加入到panel中
label = new Label();
label.Size = new Size(12, 12);
label.Location = new Point(64 + 70 * j, 30 * i);
switch (j)
{
case 0: label.Text = "+"; break;
case 1: label.Text = "="; break;
case 2: label.Name = "labelResult" + Convert.ToString(i); break;
}
panelQuestion.Controls.Add(label);
}
}
}
private void btnJudge_Click(object sender, EventArgs e)
{
if (txtTotal.Text == "")
{
MessageBox.Show("請輸入題目數!", "錯誤");
return;
}
int total = Convert.ToInt32(txtTotal.Text);
for (int i = 0; i < total; i++)
{
TextBox[] txtBox = new TextBox[3]; //用控件數組來定義每一行的TextBox,總共3個TextBox
for (int j = 0; j < 3; j++) //獲取原來已經動態添加的TextBox,這樣才能訪問
txtBox[j] = (TextBox)panelQuestion.Controls.Find("txt" + Convert.ToString(i), true)[j];
Label label = (Label)panelQuestion.Controls.Find("labelResult" + Convert.ToString(i), true)[0];
if (txtBox[2].Text == "") //如果未填答案,直接批改為錯誤
{
label.Text = "×";
continue;
}
int add = Convert.ToInt32(txtBox[0].Text) + Convert.ToInt32(txtBox[1].Text);
if (add == Convert.ToInt32(txtBox[2].Text))
label.Text = "√";
else
label.Text = "×";
}
}
}
}