22.1.9 创建对话框(1)
Toolbox窗口提供了几个标准的对话框,它们全都十分流行,但没有一个适合本程序。因为在该程序中的需要非常特殊,所以必须自己创建对话框。对话框只不过是FormBorderStyle属性值被设置为FixedDialog的窗体而已,因此在创建对话框的过程中可以从Form Designer得到大量帮助。
在主菜单上选择Project | Add New Item,或者按下Ctrl+Shift+A组合键,显示Add New Item对话框。从右边窗格的Categories:列表中选择UI,在右窗格中选择Windows Form模板,并输入名称LottoLimitsDialog。该对话框窗口是为Lotto彩票记录设置上下限时要显示的窗口。稍后将为Euromillions彩票记录创建另一个对话框窗体。单击Add按钮之后,新窗体将被添加到项目中,并显示在Editor窗口内。新对话框的类类型就是提供的名称LottoLimitsDialog。
按下F4键显示新窗体的Properties窗口。可以把Text属性值修改为Set Limits for Lotto Values,该文本将显示在对话框的标题栏中。为了使标题栏文本可见,可以拖动窗口的右边调整其宽度。还可以把Layout属性组中StartPosition属性的值设置为Center Parent,从而使该对话框窗口出现在显示它的父窗体的中心-- 本示例中的父窗体就是应用程序窗口。因为该窗体将成为对话框而非应用程序窗口,所以应该将其FormBorderStyle属性值设置为FixedDialog。该对话框窗口在显示的时候不应该被最小化或最大化,因此把Window Style组中的MinimizeBox和MaximizeBox属性设置为False,以删除最大化和最小化功能。该对话框应该通过在对话框窗口中提供的按钮关闭,因此将ControlBox属性值设置为False,从而从标题栏中删除控制和系统框。
下一步是在窗体的底部添加两个按钮,它们将成为该对话框的OK和Cancel按钮。将左边按钮的Text属性值设置为OK,将其(Name)属性设置为lottoOK。还可以把Behavior组中DialogResult属性的值设置为OK。右边按钮相同属性的值应该分别是Cancel、lottoCancel和Cancel。为按钮设置DialogResult属性值的结果是,对话框的DialogResult属性值将被设置成为了关闭对话框而单击的那个按钮的DialogResult属性值。这将使我们可以通过编程(www.cppentry.com)的方式测试用来关闭对话框的是哪个按钮,并根据该按钮是OK还是Cancel执行不同的代码。
既然已经给对话框添加了按钮,那么现在可以返回到对话框的属性窗口中,并分别把Misc属性组中AcceptButton和CancelButton属性的值设置为lottoOK和lottoCancel。这样做的结果是在该对话框显示期间,按下Enter键相当于单击OK按钮,而按下Esc键相当于单击Cancel按钮。
为了允许用户输入极限值,我们要在对话框中使用多个控件。可以使用ListBox控件让用户从可能值列表中进行选择,因此添加该控件。如图22-17所示,还应该在对话框窗体中两个ListBox控件的旁边添加两个Label控件。
|
| (点击查看大图)图 22-17 |
顶部和底部列表框的(Name)属性应该分别是lottoLowerList和lottoUpperList。从图22-17中可以看出,将ListBox控件调整为与Label控件高度相同,宽度足以显示一个极限值。作者还把字体的Size属性修改为10,把ScrollAlwaysVisible属性修改为True。确保两个列表框的SelectionMode属性都是One,因为我们希望每次只允许从列表框中选择一项。
该对话框的GUI已经完成,但为了使其做我们需要它做的事情,需要再次回到编码模式中。可以首先编写给ListBox控件提供极限值的代码。
1. 给ListBox添加列表
ListBox控件包含的列表是一组被存储为Object^类型句柄的对象,因此任何种类的对象都可以存储在列表中。在本示例中,我们希望在每个列表框中存储一组整数极限值;通常,我们能够依赖自动装箱和拆箱功能在必要时使int类型的数值与Int32类型的对象相互转换。ListBox对象的Items属性返回对列表框中对象集合的引用;该集合包含一个Add()方法,可以添加作为实参传递给列表的对象。ListBox对象具有大量的属性,其中Enabled属性当用户可以与列表框交互时值为true,当禁止交互作用时值为false。
对这两个ListBox控件来说,给列表框添加列表的基本过程是相同的,因此可以为LottoLimitsDialog类编写一个通用的、给列表框添加一组整数的私有函数成员:
- void SetList(ListBox^ listBox, int min, int max, int selected)
- {
- listBox->BeginUpdate(); // Suppress drawing the listbox
-
- for(int n = min ; n <= max ; n++)
- listBox->Items->Add(n);
-
- listBox->EndUpdate(); // Resume drawing the list box
-
- listBox->SelectedItem = Int32(selected);
- }
SetList()函数的实参是要添加列表的列表框、要添加的列表中最小和最大的整数以及列表框中要被选中的整数。该函数使用由ListBox对象的Items属性返回的集合对象所具有的Add()函数,给列表框添加从min到max(包括两者)的整数。该函数还通过将Selected设置为列表框SelectedItem属性的值,使Selected值成为显示列表框时列表中最初被选中的那一项。
当用户在该对话框中选择某个极限值时,我们需要将其放在某个地方,以便能够从属于Form1对象的函数中访问该数值。菜单项的事件处理程序有责任获取极限值,并将其存入Form1对象。一种方法是给LottoLimitsDialog类添加一对存储上、下极限值的私有成员,然后给该类添加使这两个值可以在外部使用的公有属性。给LottoLimitsDialog类的定义添加下面的代码:
- private:
- int lowerLimit; // Lower limit from control
- int upperLimit; // upper limit from control
-
- public:
- property int LowerLimit // Property accessing lower limit
- {
- int get(){ return lowerLimit; }
-
- void set(int limit)
- {
- lowerLimit = limit;
- lottoLowerList->SelectedItem = Int32(limit);
- }
- }
-
- property int UpperLimit // Property accessing upper limit
- {
- int get(){ return upperLimit; }
-
- void set(int limit)
- {
- upperLimit = limit;
- lottoUpperList->SelectedItem = Int32(limit);
- }
- }