Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 清除';全部';取消单击某些子复选框时的复选框?_C#_.net_Winforms_Checkbox - Fatal编程技术网

C# 清除';全部';取消单击某些子复选框时的复选框?

C# 清除';全部';取消单击某些子复选框时的复选框?,c#,.net,winforms,checkbox,C#,.net,Winforms,Checkbox,我有一个表单,它有几个复选框,还有一个“全部”复选框,当然,它会填充或清空其余部分。我遇到的问题是,一旦其中一个子框被取消选中,我需要它取消选中“全部”框。目前我似乎无法理解如何做到这一点的逻辑,因此任何提示都将不胜感激 以下是该项目部分的代码: public partial class SrsSelectForm : Form { /// Property to return the full SRS names for checked items public List<strin

我有一个表单,它有几个复选框,还有一个“全部”复选框,当然,它会填充或清空其余部分。我遇到的问题是,一旦其中一个子框被取消选中,我需要它取消选中“全部”框。目前我似乎无法理解如何做到这一点的逻辑,因此任何提示都将不胜感激

以下是该项目部分的代码:

public partial class SrsSelectForm : Form
{

/// Property to return the full SRS names for checked items

public List<string> SelectedSrs
{
  get
  {
    return (from cb in checkBoxes
            where cb.Checked
            select cb.Tag.ToString()).ToList();
  }
}

/// <summary>
/// Unique Srs full names for all setting nodes on the current device
/// </summary>
private HashSet<string> allSrs;

/// <summary>
/// Tracks the checkboxes generated for the available SRS
/// </summary>
private List<CheckBox> checkBoxes;

/// <summary>
/// Constructor
/// </summary>
public SrsSelectForm()
{
  InitializeComponent();

  allSrs = new HashSet<string>();
  checkBoxes = new List<CheckBox>();
}

/// <summary>
/// Event handler
/// </summary>
/// <param name="sender">this form</param>
/// <param name="e">Event args</param>
private void FormLoad(object sender, EventArgs e)
{
  // center on parent
  Utilities.SetFormLocation(this);
}

/// <summary>
/// Retrieves available SRS for the setting nodes and creates check boxes
/// for selection 
/// </summary>
/// <param name="device">currently loaded device</param>
/// <param name="folder">the user's selected output folder</param>
/// <param name="node">starting settings node</param>
public void Populate(IDevice device, string folder, TreeNode node)
{
  // find all Srs output file names
  GetSrsNames(device, folder, node);

  // generate controls for them
  CreateSrsControls();
}

/// <summary>
/// Generates checkboxes for available SRS
/// </summary>
private void CreateSrsControls()
{
  int xPos = 8;
  int yPos = 55;
  int height = 24;

  foreach (string srsPath in allSrs)
  {
    CheckBox cb = new CheckBox();

    cb.AutoSize = true;
    cb.Location = new Point(xPos, yPos);

    // friendly name
    cb.Text = Utilities.GetSrsGroupName(srsPath);

    // store full name for returning to caller
    cb.Tag = srsPath;

    cb.Checked = true;

    grpSrs.Controls.Add(cb);
    checkBoxes.Add(cb);

    yPos += height;
  }
}

/// <summary>
/// Finds all Srs for the settings tree
/// </summary>
/// <param name="device">the currently loaded device</param>
/// <param name="folder">the selected export folder</param>
/// <param name="node">a tree node</param>
private void GetSrsNames(IDevice device, string folder, TreeNode node)
{
  if (node.Tag is DeviceDefinitionNodeValue)
  {
    var nodeValue = (DeviceDefinitionNodeValue)node.Tag;

    if (nodeValue.IsRelayGroup)
    {
      string fileName = string.Empty;
      if (Utilities.GetUsableSrsFileName(device, nodeValue, folder, ref fileName))
      {
        allSrs.Add(fileName);
      }
    }
  }

  // recurse
  foreach (TreeNode subNode in node.Nodes)
  {
    GetSrsNames(device, folder, subNode);
  }
}

/// <summary>
/// Toggles the SRS checkboxes in response to the All c/b changing
/// </summary>
/// <param name="sender">checkbox control</param>
/// <param name="e">event args</param>
private void CheckedOptionChanged(object sender, EventArgs e)
{
  if (sender == cbAll)
  {
    foreach (var cb in checkBoxes)
    {
      cb.Checked = cbAll.Checked;
    }
  }
}
public分部类srs选择表单:表单
{
///属性返回选中项目的完整SRS名称
选择的公共列表SRS
{
得到
{
返回(来自复选框中的cb)
在哪里检查
选择cb.Tag.ToString()).ToList();
}
}
/// 
///当前设备上所有设置节点的唯一Srs全名
/// 
私有HashSet-allSrs;
/// 
///跟踪为可用SRS生成的复选框
/// 
私人列表复选框;
/// 
///建造师
/// 
公共SrsSelectForm()
{
初始化组件();
allSrs=newhashset();
复选框=新列表();
}
/// 
///事件处理程序
/// 
///这张表
///事件参数
私有void FormLoad(对象发送方,事件参数e)
{
//以家长为中心
实用程序.SetFormLocation(此);
}
/// 
///检索设置节点的可用SR并创建复选框
///供选择
/// 
///当前加载的设备
///用户选择的输出文件夹
///启动设置节点
公共void填充(IDevice设备、字符串文件夹、TreeNode节点)
{
//查找所有Srs输出文件名
GetSrsNames(设备、文件夹、节点);
//为它们生成控件
createSrsControl();
}
/// 
///生成可用SRS的复选框
/// 
私有void createSrsControl()
{
int xPos=8;
int yPos=55;
整数高度=24;
foreach(所有SRS中的字符串srsPath)
{
复选框cb=新复选框();
cb.AutoSize=true;
cb.位置=新点(XPO、YPO);
//友好的名字
cb.Text=Utilities.GetSrsGroupName(srsPath);
//存储用于返回给调用者的全名
cb.Tag=srsPath;
cb.Checked=真;
grpSrs.控制添加(cb);
复选框。添加(cb);
yPos+=高度;
}
}
/// 
///查找设置树的所有SR
/// 
///当前加载的设备
///选定的导出文件夹
///树节点
私有void GetSrsNames(IDevice设备、字符串文件夹、树节点)
{
如果(node.Tag是DeviceDefinitionNodeValue)
{
var nodeValue=(DeviceDefinitionNodeValue)node.Tag;
if(nodeValue.IsRelayGroup)
{
字符串文件名=string.Empty;
if(Utilities.GetUsableSrsFileName(设备、节点值、文件夹、引用文件名))
{
allSrs.Add(文件名);
}
}
}
//重现
foreach(node.Nodes中的TreeNode子节点)
{
GetSrsNames(设备、文件夹、子节点);
}
}
/// 
///切换SRS复选框以响应所有c/b更改
/// 
///复选框控件
///事件参数
私有void CheckedOptionChanged(对象发送方,事件参数e)
{
if(发送方==cbAll)
{
foreach(复选框中的var cb)
{
cb.Checked=cbAll.Checked;
}
}
}

假设您已将每个必需的复选框放入复选框列表中

if(!fromSubCheckBoxes)
foreach(CheckBox cb in checkBoxes)
    if(cbAll.Checked)
        cb.Checked = true;
    else
        cb.Checked = false;
LINQ

if(!fromSubCheckBoxes)
    checkboxes.ForEach(o => o.Checked = cbAll.Checked);
选中项目后设置
cbAll

子检查表检查更改时

if (checkboxes.Any(o => !o.Checked) && cbAll.Checked){
    fromSubCheckBoxes = true;
    cbAll.Checked = false;
    fromSubCheckBoxes = false;
}

这将导致cbAll CheckedChanged事件激发。因此,在cbAll CheckedChanged事件中抛出一个布尔值,以确保它不是由复选框列表或子复选框激发的。

您可能应该为每个复选框挂接checkbox.CheckChanged。您实际上已经声明了此事件处理程序,但我看不到它是什么在你有任何复选框钩住它之前。但是无论如何,只要让它检查一下复选框是否是“所有复选框”如果没有,则执行您想要的all复选框的逻辑。我假设这将取消选中all复选框,尽管您可以包含逻辑以查看它们是否都已被选中,在这种情况下,您可能希望实际选中“all复选框”

代码:


如果我正确理解了您的帖子,您基本上希望根据其他复选框是否全部选中来切换All复选框的状态

如果是这种情况,请考虑修改以下方法:

private void CheckedOptionChanged(object sender, EventArgs e)
{
  if (sender == cbAll)
  {
    foreach (var cb in checkBoxes)
    {
      cb.Checked = cbAll.Checked;
    }
  }
  else
  {
     cbAll.Checked = !checkBoxes.Any(cb => cb.Checked);
  }
}

当然,这假设您的所有复选框都将其用作其已更改的复选处理程序。

在您的
CheckedOptionChanged
中,只需添加
else
代码:

private void CheckedOptionChanged(object sender, EventArgs e)
{
  if (sender == cbAll)
  {
    foreach (var cb in checkBoxes)
    {
      cb.Checked = cbAll.Checked;
    }
  }
  else if (!((Checkbox)sender).Checked)
  {
    cbAll.Checked = false;
  }
}

这将设置“所有”复选框仅在未选中任何复选框时才选中;我想您可能希望
=复选框。all(cb=>cb.checked)
@zmidanen:根据我对问题的阅读,all复选框应选中其他复选框,或清除它们。这是标准行为..all(cb=>cb.checked)只有在全部选中时才会返回true,这将选中all按钮,使其与所需行为相反。@MikeHofer我认为zimdanen的意思是
!checkbox.all(cb=>cb.checked)
。他是对的;你答案中的那一行将设置
cbAll.Checked
为false,只有在没有任何选中的情况下。你也可以使用
cbAll.Checked=checkbox.any(cb=>!cb.Checked)
当选中“全部”复选框时,这会设置各个复选框;OP希望根据各个复选框设置“全部”复选框。嘿,感谢您的响应。因此,这肯定是一个进步。然而,现在发生了一件奇怪的事:当我选中“全部”复选框时,它会按预期检查所有内容,然后当我单击时其中一个子框的想法是,它应该只清除我单击的框和“全部”框,但相反,它会清除所有内容,包括“全部”框。有什么想法吗?再次感谢!可能是因为设置
cbAll.Checked
会重新触发它。在其他情况下,您可以在设置之前立即取消订阅,然后重新订阅:
cbAll.CheckedChanged-=CheckedOptionChanged;cbAll.Checked=Che
private void CheckedOptionChanged(object sender, EventArgs e)
{
  if (sender == cbAll)
  {
    foreach (var cb in checkBoxes)
    {
      cb.Checked = cbAll.Checked;
    }
  }
  else if (!((Checkbox)sender).Checked)
  {
    cbAll.Checked = false;
  }
}