查找动态创建的CheckBoxes(C ++ Windows窗体应用程序)

时间:2016-12-02 20:54:23

标签: winforms checkbox c++-cli

通过运行时我创建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

1 个答案:

答案 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
    }
}