游戏技术基础:实验三记录
net: [[C#]]
1、单选按钮控件(RadioButton控件)练习
在设计视图中,拖入一个Button和四个RadioButton,将它们排列在窗口中央。为每个RadioButton设置一个具有区分度的文本。窗口应长这样:

双击Button,添加一个点击事件处理程序:
1
2
3
4
5
6
7
8
9
10
11
12private void button1_Click(object sender, EventArgs e)
{
// 判断哪个RadioButton被选中
string city = "";
if (radioButton1.Checked) city = radioButton1.Text;
else if (radioButton2.Checked) city = radioButton2.Text;
else if (radioButton3.Checked) city = radioButton3.Text;
else if (radioButton4.Checked) city = radioButton4.Text;
// 显示选中的城市
MessageBox.Show("您选择了:" + city);
}双击Cancel按钮,使得点击该按钮为关闭窗口:
1
2
3
4
5private void button2_Click(object sender, EventArgs e)
{
// 关闭窗口
this.Close();
}运行程序,进行测试。

2、列表控件(ListBox控件)练习
打开Visual Studio,选择“Windows Forms应用程序”模板并创建新项目。
在设计器中拖入一个ListBox控件,将其放置在窗口中央,并设置一些基本属性,例如Name为listBox1,Width和Height为200,SelectionMode为MultiSimple,实际上SelectionMode属性的值可以根据实际需求进行更改。
添加一个“添加”按钮和一个“删除”按钮,并编写它们对应的事件处理程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27private void btnAdd_Click(object sender, EventArgs e)
{
string itemText = textBox1.Text.Trim();
if (string.IsNullOrEmpty(itemText))
{
MessageBox.Show("请先输入要添加的项目");
return;
}
// 调用Add方法添加新项目
listBox1.Items.Add(itemText);
// 清空文本框
textBox1.Clear();
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex == -1)
{
MessageBox.Show("请先选择要删除的项目");
return;
}
// 调用Remove方法移除选中的项目
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
}
在Add按钮单击事件中,我们首先检查文本框中是否有文本,可以通过Trim方法来去除字符串前后的空格,这里我使用了string.IsNullOrEmpty方法进行判断。如果文本框中没有输入,将弹出一个消息框进行提醒,否则将调用AddItem方法添加新项目。
在Remove按钮单击事件中,我们首先检查ListBox是否有任何项被选中,如果没有,将弹出一个消息框进行提醒,否则将使用RemoveAt方法移除选中的项目。
- 运行程序,测试看看是否可以正常工作。

3、进度条控件(ProgressBar控件)练习
打开Visual Studio,创建一个Windows Forms应用程序项目。
在窗体设计器中加入一个ProgressBar控件和一个Button控件,将按钮的Text属性设置为“开始”。
设置ProgressBar的Minimum属性为0,Maximum属性为100,Step属性为10。
在“开始”按钮的Click事件中编写代码,使进度条不断移动,直到达到最大值为止。
1
2
3
4
5
6
7
8private void button1_Click(object sender, EventArgs e)
{
while (progressBar1.Value < progressBar1.Maximum)
{
progressBar1.PerformStep();
System.Threading.Thread.Sleep(100);
}
}
在代码中,使用了while循环和System.Threading.Thread.Sleep方法。while循环的条件是进度条的值小于最大值,每循环一次,进度条的值会增加Step的值。在调用了进度条的PerformStep方法后,使用Thread.Sleep方法让线程休眠一段时间,以便观察进度条的变化,这里的休眠时间设置为100毫秒。
- 运行程序,单击“开始”按钮,观察进度条的变化。

- 继续使用label将进度显示在窗口上,就出现了问题,这里只有在进度到达100%才会显示。
1
2
3
4
5
6
7
8private void button1_Click(object sender, EventArgs e)
{
while(progressBar1.Value >= 0 && progressBar1.Value < 100) {
progressBar1.PerformStep();
System.Threading.Thread.Sleep(1000);
label1.Text = "当前进度为:" + progressBar1.Value.ToString() + "%";
}
}
经检查,原因是该代码段位于事件处理程序 button1_Click 中,当该事件被触发时,程序会执行这段代码。在执行期间,while 循环语句中的代码会一直在进行直到 progressBar1 的值达到了 100。
在这个过程中,每一次循环都会执行 label1.Text 的赋值语句。然而,这个赋值语句执行后,虽然 label1 的文本内容已经被更改了,但你并不能立即看到这些更改,因为程序还没有进入下一次循环或者方法结束。
当程序执行完成之后,最后一次更改 label1 的语句已经被执行了,然后程序结束了。所以,当 progressBar1 的值最终到达 100 时,你才能看到 label1 的内容已经被更改了。
- 为了让label能够在程序执行期间动态更新,你需要使用多线程来执行
while循环以及更新label1的操作,这样就可以避免程序在等待循环结束前暂停主线程的执行,从而能够让用户实时观察到label1的更改。你可以修改代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private void button1_Click(object sender, EventArgs e)
{
// 创建新线程
Thread newThread = new Thread(delegate ()
{
while (progressBar1.Value < 100)
{
progressBar1.Invoke(new Action(() => progressBar1.PerformStep()));
label1.Invoke(new Action(() => label1.Text = "当前进度为:" + progressBar1.Value.ToString() + "%"));
Thread.Sleep(1000);
}
});
// 启动线程
newThread.Start();
}
在这个修改后的代码中,当 button1 被点击时,会创建一个新线程,并在新线程中执行 while 循环以及更新 label1 的操作。使用了 Invoke 方法来确保在主线程执行更新 progressBar1 和 label1 的操作,然后通过 Thread.Sleep 方法使新线程暂停 1 秒钟。这样,你就可以在程序执行期间观察到 label1 的更新了。
- 还有一种方法是使用
async/await关键字来异步执行循环及更新操作,代码如下:在修改后的代码中,1
2
3
4
5
6
7
8
9private async void button1_Click(object sender, EventArgs e)
{
while (progressBar1.Value < 100)
{
progressBar1.PerformStep();
label1.Text = "当前进度为:" + progressBar1.Value.ToString() + "%";
await Task.Delay(1000);
}
}button1_Click方法被声明为异步方法,while循环及更新progressBar1和label1的操作被包含在异步执行的任务中,通过await Task.Delay(1000)方法使任务暂停 1 秒钟。这样,你也能在程序执行期间观察到label1的更新了。
请注意,如果使用 async/await 关键字来异步执行循环及更新操作,你还需考虑到是否会在更新 label1 的过程中出现某些异常,如线程安全问题等,需要进行一定的异常处理。
- 测试结果

