Unchecking ListViewItems recursively - c#

I have a ListView with cascading checkboxes inside of it. What I would like to do is be able to uncheck all child boxes if the parent box is unchecked (and similarly I'd like to check all child boxes if the parent is checked). Currently, if I check or uncheck a box, the parent node and child nodes are greyed out, but the check mark is still visible on the child boxes.
I presume I'd have to do this recursively. I've given the following code a try and I think it should work, but it breaks at runtime due to casting issues.
private void listViewChildNodeModifier(ListViewItem item)
{
if (item.SubItems.Equals(null)) return;
else
{
foreach (ListViewItem childItem in item.SubItems)
{
listViewChildNodeModifier(childItem);
if(childItem.Tag is TestingNode)
((TestingNode)childItem.Tag).Enabled = item.Checked;
}
}
}

Could you not do this
foreach (ListViewItem item in this.ListView.Items)
{
for (int i = 0; i < item.SubItems.Count; i++)
{
item.SubItems[i].Checked = false;
//will something like this work for you let me know
}
}
another alternative which should work as well would be the following
foreach (ListViewItem.ListViewSubItem childItem in item.SubItems)
{
if(item.Checked)
{
item.Checked = false;
}
}

Related

C# - Menustrip- Check if Parent exists and get the reference to them

First of all Thanks for your Time! I hope you can help me =/
I have a MenuStrip where i want to add items dynamically.
What i want to do :
If a Partent with exactly the same name already exists the Childs should be add to this parent instead creating a new Parent(MenuStripItem) with the same name.
My Code does currently checks if the parent already exists (which works fine) but the problem is i cant get the reference to this parent -> firstItem=var doesnt work -> cant convert ToolStripItem to ToolStripMenuItem... and changing the "firstItem" to ToolStripItem gives me an Error because i cant use "firstItem.DropDownItems.Add(withChild);" anymore to add a Child later on...
private void AddNewMenuStrips(string [,] NewMenuStripInfo)
{
ToolStripMenuItem firstItem;
bool alreadyexists = false;
string someItem = "Settings"; // the parent im looking for
var items = menuStrip2.Items.Find(someItem+"ToolStripMenuItem",false); //here it checks if parent already exists. Which Works but i cant get the reference of the parent to "firstItem"
foreach (var item in items)
{
MessageBox.Show("FOUND"+item.Name);
firstItem = var; // ERROR cant convert ToolStripItem to ToolStripMenuItem
alreadyexists=true;
}
if (alreadyexists == false) { firstItem = new ToolStripMenuItem(someItem); }
}
THANKS in advance!
ToolStripMenuItem is a class which represents top level menu items and derives (not directly) from ToolStripItem.
Therefore to retrieve the parent menu item you can use a cast:
foreach (var item in parents)
{
MessageBox.Show("FOUND" + item.Name);
firstItem = item as ToolStripMenuItem;
alreadyexists = true;
// break;
}

VisualStudio c# foreach on checkbox

I have this code and it seems like it should work but for some reason it doesnt.
foreach(Control c in Controls.OfType<CheckBox>()) {
Check_checked += 1;
}
** Check edit: When I step through the code the Control c is picking up all of the textboxes but nothing else.
Any help would be appreciated.
**I realise that ofType should not be picking up text/labels/watever.
Im getting text/labels/watever.
I moved my code to another computer also running visual studio. It doesnt pickup checkboxes and it doesnt seem to be bugging about picking up text/label/watever on that system.
So I think one of the issues is my VS is bugger-up. Will re-install now.
look at following answer
Get all controls of a specific type
Code check if the control is a ContainerControl and then iterates over all the children of that control to find the controls of type.
public static IEnumerable<T> GetControlsOfType<T>(Control root)
where T : Control
{
var t = root as T;
if (t != null)
yield return t;
var container = root as ContainerControl;
if (container != null)
foreach (Control c in container.Controls)
foreach (var i in GetControlsOfType<T>(c))
yield return i;
}
Then you could do something like this:
foreach (var pictureBox in GetControlsOfType<CheckBox>(form)) {
}
This code is a simple solution for counting checkboxes on a form that are checked.
private int CountChecks(IEnumerable controls)
{
var result = 0;
foreach (Control xControl in controls)
{
if (xControl.HasChildren) result += CountChecks(xControl.Controls);
if (!(xControl is CheckBox)) continue;
if (!(xControl as CheckBox).Checked) continue;
result++;
}
return result;
}
you might use this in this manner:
var howManyAreChecked = CountChecks(Controls);
This would have to be in a form to use this syntax. You must pass a forms Controls into the method in order to work correctly.

Accessing unknown child

In my code, I need to find a child of a child of a child.
Only the first child will always be the same child but the child of the child is randomized between 4 different possible prefabs.
on that last child I want to disable it's image.
here would be the ideal code if the child wouldn't be randomized between others:
protected void SetUnpickedPrizesVisibility(bool isVisible)
{
foreach (var element in list)
{
if (!element.IsPicked)
{ element.transform.FindChild("FirstChild").FindChild("SecondChild").FindChild("ThirdChild").GetComponent<Image>().enabled = false;
}
}
}
But since, the SecondChild varies, I can't simply do that.
Is my only option to do something like this?
protected void SetUnpickedPrizesVisibility(bool isVisible)
{
foreach (var element in list)
{
if (!element.IsPicked)
{
if(element.transform.FindChild("FirstChild").FindChild("SecondChild1"))
element.transform.FindChild("FirstChild").FindChild("SecondChild1").FindChild("ThirdChild").GetComponent<Image>().enabled = false;
if(element.transform.FindChild("FirstChild").FindChild("SecondChild2"))
element.transform.FindChild("FirstChild").FindChild("SecondChild2").FindChild("ThirdChild").GetComponent<Image>().enabled = false;
if(element.transform.FindChild("FirstChild").FindChild("SecondChild3"))
element.transform.FindChild("FirstChild").FindChild("SecondChild3").FindChild("ThirdChild").GetComponent<Image>().enabled = false;
}
}
}
Or does someone have a different idea?
I know this is a very confusing to read question but I tried my best to simplify it.
Thanks,
So why not add a script to the prefab of the last child that disables the image. That way you only need to keep a reference to the script when you instantiate it and not go looking for the children.
You can just search through, something like this:
foreach (var element in list)
{
if (!element.IsPicked)
{
foreach(var grandChild in element)
{
foreach(var greatGrandChild in grandChild)
{
greatGrandChild.GetComponent<Image>().enabled = false;
}
}
}
}
It's easier to use child, grandChild and greatGrandChild rather than child of the child of child :-)

get all controls of a type and change their properties

in my software I have a TabControl and I want to search for all Controls of a certain type using foreach (for example) and change some of there properties.
Now when I do something like this:
Control ctrl;
ctrl = My_CheckedListBox;
((CheckedListBox)ctrl).SetItemChecked(0, false);
It works fine and the checkboxes all get unchecked, no problem. But when I use foreach they don't:
foreach (Control item in ModuleTab.Controls)
{
if (item is CheckedListBox)
{
for (int i = 0; i < ((CheckedListBox)item).Items.Count; i++)
{
((CheckedListBox)item).SetItemChecked(i, false);
}
}
}
I know it is because item is not really the Control but an object. I wonder if there is something like:
foreach (Control ref item in ModuleTab.Controls)
Any help?
So I solved it! Jon Skeet was right. The Tab in the TabControl didn't contain the controls I was looking for because they were all in a GroupBox!
I searched for them in the GroupBox and there they were. The CheckBoxes where unchecked and everything worked perfectly as it should.
#Jon Thx for the "observing" tip. I let the program show me the available Controls in the Tab using a MessageBox and that is how I solved it. Thx also for the user who deleted his answer because he interduced me to the OfType<>() method.That really made the code look better:
foreach (var groupbox in ModuleTab.Controls.OfType<GroupBox>())
{
foreach (var item in groupbox.Controls.OfType<CheckedListBox>())
{
for (int i = 0; i < item.Items.Count; i++)
{
item.SetItemChecked(i, false);
}
}
}
foreach (Control item in ModuleTab.Controls)
{
if (item.GetType() == typeof(CheckedListBox)))
{
for (int i = 0; i < item.Items.Count; i++)
{
item.SetItemChecked(i, false);
}
}
}

foreach control c# skipping controls

I have the following loop to remove the buttons in my C# Windows Forms application. The only problem is that it skips every other button. How do I go about removing all the button controls from my form?
foreach (Control cntrl in Controls)
{
if(cntrl.GetType() == typeof(Button))
{
Controls.Remove(cntrl);
cntrl.Dispose();
}
}
I think this way is a bit more readable:
var controlsToRemove = Controls.OfType<Button>().ToArray();
foreach (var control in controlsToRemove)
{
Controls.Remove(control);
cntrl.Dispose();
}
Calling ToArray() makes a new concrete collection, so that you can enumerate over one and modify the other.
Surprised that's not erroring on you, since you're modifying the collection as you're iterating over it. Use a for loop and start at the end:
for (int ii = Controls.Count - 1; ii >= 0; ii--)
{
Control cntrl = Controls[ii];
Controls.remove(cntrl);
cntrl.Dispose();
}
(Starting at the end because otherwise you'd be changing the indexes of each control as you iterated.)
Youre iterating over the same collection from whitch youre removing. Use this code:
List<Control> cleanControls = new List<Control>();
foreach(Control ctr in Controls)
{
if(cntrl.GetType() != typeof(Button))
{
cleanControls.Add(ctr);
}
else
{
ctr.Dispose();
}
}
Controls = cleanControls;
That's It!
Hope I helped!

Categories

Resources