I am creating an "export to excel" windows form in c#. The class contains a CheckedListBox and a "check all" button. When clicking on the button I want to check all the items in the list in case that at least one checkbox is not checked or uncheck all the checkboxes in case they are all already checked.
I added a small complication, the list of the items is a list of custom objects (see private class inside): "ObjectToExport" class.
public partial class ExcelCustomExportForm : Form
{
private class ObjectToExport
{
private readonly IExcelExportable _form;
public ObjectToExport(IExcelExportable form)
{
_form = form;
}
public override string ToString()
{
return $"{_form.FormName} ({_form.CreatedDate.ToShortDateString()} {_form.CreatedDate.ToShortTimeString()})";
}
}
// each form in the list contains a gridview which will be exported to excel
public ExcelCustomExportForm(List<IExcelExportable> forms)
{
InitializeComponent();
Init(forms);
}
private void Init(List<IExcelExportable> forms)
{
foreach (IExcelExportable form in forms)
{
// Checked List Box creation
FormsCheckedListBox.Items.Add(new ObjectToExport(form));
}
}
private void CheckAllButton_Click(object sender, EventArgs e)
{
// checking if all the items in the list are checked
var isAllChecked = FormsCheckedListBox.Items.OfType<CheckBox>().All(c => c.Checked);
CheckItems(!isAllChecked);
}
private void CheckItems(bool checkAll)
{
if (checkAll)
{
CheckAllButton.Text = "Uncheck All";
}
else
{
CheckAllButton.Text = "Check All";
}
FormsCheckedListBox.CheckedItems.OfType<CheckBox>().ToList().ForEach(c => c.Checked = checkAll);
}
}
The problem is that the following line returns true even if not check box is checked:
var isAllChecked = FormsCheckedListBox.Items.OfType<CheckBox>().All(c => c.Checked);
Similar issue with the following line, if checkAll is true, no check box is checked:
FormsCheckedListBox.CheckedItems.OfType<CheckBox>().ToList().ForEach(c => c.Checked = checkAll);
What is the correct way to fix those two lines of code?
Your Problem begins here.
FormsCheckedListBox.Items.Add(new ObjectToExport(form));
and
var isAllChecked = FormsCheckedListBox.Items.OfType<CheckBox>().All(c => c.Checked);
You are adding instances of 'ObjectToExport
' to the FormsCheckedListBox, but while filtering, you are checking filtering with CheckBox
.
This means, your filtered query always return empty, and query never reaches All. This can be demonstrated with following example.
var list = new [] { 1,2,3,4};
var result = list.OfType<string>().All(x=> {Console.WriteLine("Inside All"); return false;});
The result of above would be True
, and it would never print the "Inside All" text. This is what is happening with your queries.
You can find if any of the checkbox is checked using
var ifAnyChecked = checkedListBox1.CheckedItems.Count !=0;
To change state, you could do the following.
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if (checkedListBox1.GetItemCheckState(i) == CheckState.Checked)
{
// Do something
}
}