22.1.11 添加第二个对话框(2)
各个属性的get()函数返回该对话框类中对应的私有成员的值。set()函数设置相应数据成员的值,并更新对话框中的控件,使新值成为选中值。SelectedIndex属性值是选中项的索引。使用ComboBox控件的FindString()函数设置SelectedIndex属性,该函数返回控件的数据项集合中第一个与实参相同的数据项的索引值。该位置的数值最初显示在控件中。
在Design窗口中双击EuroLimitsDialog类中的OK按钮,添加该按钮的Click事件处理程序。不需要实现Cancel按钮的处理程序。可以像下面这样实现OK按钮的处理程序:
- System::Void euroOK_Click(System::Object^ sender, System::EventArgs^ e)
- {
- ::DialogResult result;
-
- // get the limits for values
- int valuesLower = Decimal::ToInt32(lowerValuesLimits->Value);
- int valuesUpper = Decimal::ToInt32(upperValuesLimits->Value);
- if(valuesUpper - valuesLower < 4) // Check for an adequate range
- {
- result = MessageBox::Show(this, // Range insufficient so
- "Upper values limit: "+valuesUpper + // display message box
- " Lower values limit: "+ valuesLower+
- "\nUpper values limit must be at least 4 greater that the lower
- limit."+"\nTry Again.",
- "Limits Invalid",
- MessageBoxButtons::OKCancel,
- MessageBoxIcon::Error);
-
- if(result == ::DialogResult::OK) // If message box OK clicked
- DialogResult = ::DialogResult::None;// prevent dialog from closing
- else // Messag box Cancel clicked
- DialogResult = ::DialogResult::Cancel; // so close the dialog
- return;
- }
-
- // Get stars limits
- int starsLower = lowerStarsLimits->SelectedItem == nullptr
- lowerStarsLimit :
- Int32::Parse(lowerStarsLimits->SelectedItem->ToString());
- int starsUpper = upperStarsLimits->SelectedItem ==
- nullptr
- upperStarsLimit :
- Int32::Parse(upperStarsLimits->SelectedItem->ToString());
- if(starsUpper - starsLower < 1) // Check for an adequate range
- {
- result = MessageBox::Show(this, // Range insufficient so
- "Upper stars limit: "+starsUpper + // so display message box
- " Lower stars limit: "+ starsLower+
- "\nUpper stars limit must be at least 1 greater that the lower limit."+
- "\nTry Again.",
- "Limits Invalid",
- MessageBoxButtons::OKCancel,
- MessageBoxIcon::Error);
- if(result == ::DialogResult::OK) // If message box OK clicked
- DialogResult = ::DialogResult::None; // prevent dialog from closing
- else // Message box Cancel clicked
- DialogResult = ::DialogResult::Cancel;// so close the dialog
- }
- // Store the new limits
- lowerValuesLimit = valuesLower;
- upperValuesLimit = valuesUpper;
- lowerStarsLimit = starsLower;
- upperStarsLimit = starsUpper;
- }
NumericUpDown控件的Value属性返回Decimal类型的数值。为了把该数值转换为Int32类型,将其作为实参传递给Decimal类中的静态ToInt32()函数。该函数返回的数值被自动拆箱,因此可以存入int类型的变量中。
ComboBox控件的SelectedItem属性返回的值属于Object^类型,因此为稳妥起见,我们要检查一下该值是否为空。如果是空值,就把局部变量设置为对话框对象中存储的当前值;如果不是空值,就存储SelectedItem属性表示的数值。不能直接存储该数值,而应该为该对象调用ToString()函数,产生该对象的字符串表示,然后使用Int32类中的静态Parse()函数,将其转换为可以存储的int类型。
Form1类需要添加一个私有成员来存储新对话框的句柄:
- private:
- EuroLimitsDialog^ euroLimitsDialog; // Dialog to set Euromillions limits
在Form1类的构造函数中,可以在代码最后添加下面的语句以创建该对话框对象,并更新表示星值组极限值的属性:
- euroLimitsDialog = gcnew EuroLimitsDialog;
- euroLimitsDialog->LowerStarsLimit = euroStarsLowerLimit;
- euroLimitsDialog->UpperStarsLimit = euroStarsUpperLimit;
通过设置对话框对象的LowerStarsLimit和UpperStarsLimit属性,可以确保两个ComboBox控件在对话框一开始出现时就显示这里设置的数值。如果不为ComboBox控件设置选中项,则这种控件最初将什么也不显示。
不要忘记给Form1.h文件添加嵌入EuroLimitsDialog类定义的#include指令:
- #include "EuroLimitsDialog.h"
2. 禁用输入控件
当Limits | Upper菜单项被单击时,我们希望禁止输入下限值;而当Limits | Lower菜单项被单击时,我们希望禁止输入上限值。可以给EuroLimitsDialog类添加一对成员函数来实现这样的限制:
- public:
- // Disables controls for selecting upper limits
- void SetLowerEnabled(void)
- {
- upperValuesLimits->Enabled = false;
- upperStarsLimits->Enabled = false;
- lowerValuesLimits->Enabled = true;
- lowerStarsLimits->Enabled = true;
- }
-
- // Disables controls for selecting lower limits
- void SetUpperEnabled(void)
- {
- upperValuesLimits->Enabled = true;
- upperStarsLimits->Enabled = true;
- lowerValuesLimits->Enabled = false;
- lowerStarsLimits->Enabled = false;
- }
控件的Enabled属性值决定着是否启用该控件。为true值时启用控件,而为false值时禁用控件,因此用户不能再与其交互。SetLowerEnabled()函数禁用了两个用来输入上限值的控件,并启用了两个输入下限值的控件。SetUpperEnabled()函数的功能刚好相反。
3. 更新Limits菜单项的处理程序
为了完成对输入Euromillions彩票极限值的支持,最后一步是更新Form1类中Limits菜单的Click事件处理程序。Upper菜单项的处理程序应该修改成下面这样:
- System::Void upperMenuItem_Click(System::Object^ sender,
- System::EventArgs^ e)
- {
- ::DialogResult result;
- if(lottoTab->Visible)
- {
- lottoLimitsDialog->SetUpperEnabled();
- result = lottoLimitsDialog->ShowDialog(this);
- if(result == ::DialogResult::OK)
- {
- lottoUserMaximum = lottoLimitsDialog->UpperLimit;
- lottoUserMinimum = lottoLimitsDialog->LowerLimit;
- }
- }
- else if(euroTab->Visible)
- {
- euroLimitsDialog->SetUpperEnabled();
- result = euroLimitsDialog->ShowDialog(this);
- if(result == ::DialogResult::OK)
- {
- euroUserMaximum = euroLimitsDialog->UpperValuesLimit;
- euroUserMinimum = euroLimitsDialog->LowerValuesLimit;
- euroStarsUserMaximum = euroLimitsDialog->UpperStarsLimit;
- euroStarsUserMinimum = euroLimitsDialog->LowerStarsLimit;
- }
- }
- }
局部变量result用在两条if语句中,因此在函数的开始处声明该变量。在调用对话框对象中的SetUpperEnabled()函数以启用对话框中适当的控件之后,以模态形式显示该对话框。如果用户通过单击OK按钮关闭对话框,就存储通过对话框对象的属性获得的结果。
对Lower菜单项Click事件处理程序函数的修改非常类似:
- System::Void lowerMenuItem_Click(System::Object^ sender,
- System::EventArgs^ e)
- {
- ::DialogResult result;
- if(lottoTab->Visible)
- {
- lottoLimitsDialog->SetLowerEnabled();
- result = lottoLimitsDialog->ShowDialog(this);
- if(result == ::DialogResult::OK)
- {
- lottoUserMaximum = lottoLimitsDialog->UpperLimit;
- lottoUserMinimum = lottoLimitsDialog->LowerLimit;
- }
- }
- else if(euroTab->Visible)
- {
- euroLimitsDialog->SetLowerEnabled();
- result = euroLimitsDialog->ShowDialog(this);
- if(result == ::DialogResult::OK)
- {
- euroUserMaximum = euroLimitsDialog->UpperValuesLimit;
- euroUserMinimum = euroLimitsDialog->LowerValuesLimit;
- euroStarsUserMaximum = euroLimitsDialog->UpperStarsLimit;
- euroStarsUserMinimum = euroLimitsDialog->LowerStarsLimit;
- }
- }
- }
这里的逻辑与上一个处理程序中的逻辑相同。