如何在C#的Windows窗体中获取动态添加控件的值?

7

我阅读了一些文章,但没有解决我的问题。我的问题是当我尝试获取动态添加到Windows表单中的控件(复选框和组合框)的值时,我需要知道当按下按钮时,复选框是否被选中(或未选中),以及组合框是否为空(或非空)。这个按钮调用一个方法,在该方法中我会验证所有组件是否为空。我以以下方式添加控件:

 CheckBox box;
 ComboBox cmBox;
 for (int i = 1; i <= sumOfRegisters; i++)
 {
    box = new CheckBox();
    box.Name = "CheckBox" + i;
    box.Text = "Some text";
    box.AutoSize = true;
    box.Location = new Point(10, i * 25); //vertical

    cmBox = new ComboBox();
    cmBox.Name = "ComboBox" + i;
    cmBox.Size = new System.Drawing.Size(302, 21);
    cmBox.TabIndex = i;
    cmBox.Text = "Some Text";
    cmBox.Location = new Point(270, i * 25);

    this.groupBox.Controls.Add(cmBox);
    this.groupBox.Controls.Add(box);
}

"针对ComboBox,我从数据库中添加值,这部分我省略了。"

我尝试使用foreach获取值:

foreach (Control ctrl in groupBox.Controls)

问题是我不知道如何判断控件(CheckBox 和 ComboBox)是否被选中或为空(这两种情况都要考虑)。
非常感谢您的帮助,我非常感激您的时间。

我建议您查看 DataRepeater 控件。 - Ben N
你是否在迭代 groupBox.Controls 时不确定控件的类型? - JNYRanger
将两个控件分别放在不同的 foreach 语句中可能是值得的:var CheckBox chk; foreach (chk in groupbox.Controls)var ComboBox cmb; foreach (cmb in groupbox.Controls) - Ben
5个回答

3

在将动态分配的控件添加到grbMateias后,您正在丢弃对每个控件的引用。

一种选择是将这些引用存储在例如List<Control>中。

List<ComboBox> comboBoxes = new List<ComboBox>();

for (int i = 1; i <= sumOfRegisters; i++)
{
    box = new CheckBox();
    comboBoxes.Add(box);
    // etc.
}

您可以遍历grbMateias中的控件。
 foreach(Control ctl in grbMateias.Controls)
 {
     if (ctl is CheckBox)
     {
         // Use the checkbox
     }    
     else if (ctl is ComboBox)
     {
         // Use the ComboBox
     }    
 }

或者使用Linq。
var comboBoxes = grbMateias.Controls.OfType<ComboBox>();
var checkBoxes = grbMateias.Controls.OfType<CheckBox>();

2
您可以使用as运算符,如下所示:
foreach (Control ctrl in groupBox.Controls)
{
    CheckBox checkBox = ctrl as CheckBox;
    ComboBox comboBox = ctrl as ComboBox;

    if (checkBox != null)   // Control is a CheckBox
    {
        if (checkBox.Checked)
        {
            // CheckBox is checked
        }
        else
        {
            // CheckBox is not checked
        }
    } 
    else if (comboBox != null)  // Control is a ComboBox
    {
        if (comboBox.Items.Count == 0)
        {
            // ComboBox is empty
        } 
        else
        {
            // ComboBox isn't empty
        }
    }
}

感谢您的回答和宝贵时间,我已经通过您的答案解决了我的问题。 - Fernando Bernal

1

由于在循环中为每个控件命名,因此很容易使用它来识别每个单独的控件,只要名称是唯一的。例如,要获取第三个复选框,可以使用以下代码:

Control control = groupBox.Controls.Single(x => x.Name == "CheckBox3");
Checkbox thirdCheckBox = (CheckBox)control;
bool checkBoxCheched = thirdCheckBox.Checked;

1

首先,您需要知道在迭代时使用的控件是什么,然后您可以进行强制转换并使用该特定控件的方法。

foreach(Control c in groupBox.Controls)
{
    if(c is ComboBox)
    {
         if((ComboBox) c).SelectedItem == null)
            //handle nothing entered
    }
    else if(c is CheckBox)
    {
        if((CheckBox) c).Checked)
            //handle checked
    }
}

在上面的代码片段中,我们使用is关键字检查控件的类型。然后,如果它是我们知道如何处理的控件,我们进行强制转换并检查是否为空或已选中。

1

我需要知道复选框被选中(或未选中)以及组合框是否为空(或非空)的状态。

要获取您的复选框和组合框的状态,包括您用于创建它们的索引,可以执行以下操作:

var checkBoxStates = groupBox.Controls
    .OfType<CheckBox>
    .Where(x => x.Name.StartsWith("CheckBox"))
    .Select(x => new {
        Index = Int.Parse(x.Name.Substring("CheckBox".Length)), 
        IsChecked = x.Checked
    })
    .ToList();

var comboBoxStates = groupBox.Controls
    .OfType<ComboBox>
    .Where(x => x.Name.StartsWith("ComboBox"))
    .Select(x => new {
        Index = Int.Parse(x.Name.Substring("ComboBox".Length)), 
        IsEmpty = x.Items.Count == 0
    })
    .ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接