通过运行时我创建CheckBoxes:
unsigned int number = getNumber();
CheckBox^ box;
for(unsigned int i = 1; i <= number; i++)
{
box = gcnew CheckBox();
box->Name = i.ToString();
box->Text = i.ToString();
box->AutoSize = true;
box->Location = Point(10, i * 30);
this->panel->Controls->Add(box);
}
现在我想要获取所有未检查的CheckBox:
std::map<unsigned int, std::string> values;
for (unsigned int i = 1; i <= number; i++)
{
String^ name = i.ToString();
CheckBox^ box = dynamic_cast<CheckBox^>(this->panel->Controls->Find(name, true));
if (!box->Checked)
{
String^ text = box->Text;
values.insert(std::pair<unsigned int, std::string>(i, msclr::interop::marshal_as<std::string>(text)));
}
}
我的问题是,在运行时我得到一个NullReferenceException(在行中我检查是否取消选中该框)。 但是所有CheckBox都存在。
PS:我正在使用Visual Studio 2015社区更新3
答案 0 :(得分:0)
根据MSDN,Find的签名是:
array<Control^>^ Find(
String^ key,
bool searchAllChildren
)
它返回一个数组。但是你将dynamic_casting
改为{Check} ^。这失败了,所以返回一个NULL指针。
您可以使用
制作代码 CheckBox^ box = dynamic_cast<CheckBox^>(this->panel->Controls->Find(name, true)[0]);
这将动态地将控件数组的第一个元素转换为复选框,这就是你想要的。
通常情况下,您应该找到一种方法来遍历数组中的所有内容,但在这种情况下,由于您确定find将返回一个且只返回一个结果,因此使用[0]表示法是可以的。
注意,您甚至不需要Find
。 (它效率不高。)你应该能够迭代this->panel->Controls
。我不擅长托管C ++,但它应该是:
foreach (control in this->panel->Controls)
{
if (control is CheckBox and static_cast<CheckBox^>(control).Checked) {
// do your stuff
}
}