昨天晚上回寢室看到室友正在被一個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 = "×"; } } } }