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