检测是不是未选中任何复选框以更新复选框列表

Posted

技术标签:

【中文标题】检测是不是未选中任何复选框以更新复选框列表【英文标题】:Detect if any checkbox is unchecked to update a list of checkboxes检测是否未选中任何复选框以更新复选框列表 【发布时间】:2022-01-12 19:07:45 【问题描述】:

我有 2 个最初选中的复选框列表,我需要知道用户是否未选中 any 复选框(左侧),以便在不循环的情况下更新右侧的相应复选框状态每次用户单击时复选框的更改状态:

这是我目前创建列表的解决方案:

        List<string> statuts_gauche = new List<string>  "005", "006" , "017" , "030", "031", "033", "035", "036", "026", "009", "022", "328", "329";
    List<string> statuts_droite = new List<string>();
    

    public Form1()
    
        InitializeComponent();
    

    private void button1_Click(object sender, EventArgs e)
    
        Console.WriteLine("hello");
        foreach (Control c in this.Controls)
        
            if (c is CheckBox)
            
                CheckBox box= (CheckBox)c;
                Console.WriteLine("hh - " + box.Text + " : " + box.Checked );
            
        
    
    private void Form1_Shown(object sender, EventArgs e)
    

        Create_Checkboxes_ByTag("statuts_gauche",40);
        statuts_droite = statuts_gauche;
        Create_Checkboxes_ByTag("statuts_droite", 300);

    

    private void Create_Checkboxes_ByTag(String Tag,int initialOffset,int y_position = 30) 
        CheckBox box;

        for (int i = 0; i < statuts_gauche.Count; i++)
        
            box = new CheckBox();
            box.Tag = Tag;
            box.Text = statuts_gauche[i].ToString();
            box.AutoSize = true;
            box.Checked = true;
            box.Location = new Point(initialOffset, y_position);
            y_position = y_position + 40;
            this.Controls.Add(box);
        
    

【问题讨论】:

我发布完答案后,您没有额外的实施细节。在您的 Create_Checkboxes_ByTag 函数中,为您的复选框复选框指定一个唯一名称。这允许您执行this.Controls["nameofcheckbox"],然后只需确保您的名字是您可以轻松获取左侧复选框的名称并将其转换为右侧复选框的名称。 【参考方案1】:
private void chkLeft_CheckedChanged(object sender, EventArgs e)

    if (sender as CheckBox lchk)
    
        string name = lchk.Name.Replace("Left", "Right");
        CheckBox rchk = pnlRight.Controls(name) as CheckBox;
        rchk.Checked = lchk.Checked;
    

^ 此代码假设您未提供实现细节。 首先,对于所有“左”复选框,您需要将此通用事件处理程序添加到它们的每个 CheckedChanged 事件中。 IE,类似:

foreach (ctl in pnlLeft.Controls)

    if (ctl as CheckBox chk)
    
        ctl.CheckedChanged += chkLeft_Changed;
    

这还假设您在一个父容器控件中具有左侧复选框,而右侧复选框位于另一个父容器中。当然,如果他们共享一个容器,那么您将不得不在上述 foreach 循环中过滤名称。

接下来,假设您将控件命名为“chkLeft022”和“chkRight022”之类的名称,以便它们的名称紧密配对,您只需一个简单的字符串即可从左到右(反之亦然)替换控件名称中的单词 left 或 right。

您可以采用仅基于索引的无名路线(例如 pnlLeft.Controls[0] 与 pnlRight.Controls[0] 配对),但您需要确保顺序始终正确。

【讨论】:

一个警告,它还假设总是有一个名为 chkRight 的第二个控件匹配。所以在上面的代码中CheckBox rchk = pnlRight.Controls(name) as CheckBox; 你会得到一个除非父容器中不存在具有该名称的复选框。所以基本上,上面的一些代码很脆弱。 我不认为它很脆;不是说用户可以更改名称,然后代码成对创建它们吗? @CaiusJard 没错,我说的更多来自个人经验,后来的更改破坏了类似的东西,因为我添加了不同类型的控件或其他效果。【参考方案2】:

如果您愿意同时创建您的盒子,您可以轻松地将它们绑在一起:

private void Create_Checkboxes_ByTag(string tag,int initialOffsetLeft, int initialOffsetRight,int y_position = 30) 
   
    for (int i = 0; i < statuts_gauche.Count; i++)
    
        var box = new CheckBox() 
          Tag = tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetLeft, y_position)
        ;
        this.Controls.Add(box);

        var boxr = new CheckBox() 
          Tag = Tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetRight, y_position)
        ;
        this.Controls.Add(box);

        box.CheckedChanged += (_,_) => boxr.Checked = box.Checked;

        y_position = y_position + 40;
    

一个辅助方法也可以清理一些..

如果您想坚持一次创建单列框,请在创建框时将框添加到列表中并将其返回。在下次调用时传递列表(创建右侧框),然后您可以通过索引找到等效的左侧框,以便在左侧添加一个引用右侧的事件处理程序,也许:

private List<CheckBox> Create_Checkboxes_ByTag(string tag, int initialOffset, List<CheckBox> lefts = null, int y_position = 30) 
   
    var boxes = new List<CheckBox>();
    for (int i = 0; i < statuts_gauche.Count; i++)
    
        var box = new CheckBox() 
          Tag = tag,
          Text = statuts_gauche[i].ToString(),
          Checked = true,
          Location = new Point(initialOffsetLeft, y_position);
        ;
        this.Controls.Add(box);

        boxes.Add(box);

        var leftBox = lefts?[i];
        if(leftBox != null)
          leftBox.CheckedChanged += (_,_) => box.Checked = leftBox.Checked;

        y_position = y_position + 40;
    
    return boxes;

然后你只需要在第一次调用时捕获返回列表,并在下次调用时反馈它。

【讨论】:

以上是关于检测是不是未选中任何复选框以更新复选框列表的主要内容,如果未能解决你的问题,请参考以下文章

即使未从 HTML 检查到 PHP,如何获取所有复选框变量?

我如何确定是不是选中了复选框以执行某些操作,然后未选中执行其他操作? [复制]

当我在 Android 上滚动列表视图时复选框未选中

如果提交表单时未选中复选框,如何将布尔值更新为 0

从复选框列表中设置复选框以使用 jquery 取消选中

有没有办法在提交之前检查表单以查看是不是已选中任何复选框?