查找动态创建的复选框(C++ Windows 表单应用程序)

Find dynamically created CheckBoxes (C++ Windows Form Application)

我在运行时创建复选框:

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);      
}

现在我想获取所有未选中的复选框:

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(在我检查该框是否未选中的行中)。 但是所有复选框都存在。

PS:我正在使用 Visual Studio 2015 社区更新 3

根据MSDN,Find的签名是:

array<Control^>^ Find(
    String^ key,
    bool searchAllChildren
)

它return是一个数组。但是你 dynamic_casting 它到一个 CheckBox^。这失败了,所以 return 是一个 NULL 指针。

您可以让您的代码与

一起工作
    CheckBox^ box = dynamic_cast<CheckBox^>(this->panel->Controls->Find(name, true)[0]);

这会将控件数组的第一个元素动态转换为复选框,这就是您想要的。

通常,您应该找到一种方法来遍历数组中的所有内容,但在这种情况下,由于您确定 find 将 return 一个且只有一个结果,因此使用 [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
    }
}