简体   繁体   中英

How do I use foreach() on a control to manipulate another control?

I'm making a UI in winform, I'm using VS2015 to create the winform. The UI is subdivided into multiple pages by a tab control. In one of the tab page along with other things (picture box, text box, buttons etc.) I have 8 check box named cb1 ~ cb8, and 8 horizontal scroll bar named scrjoint1 ~ scrjoint8.

The scroll bar is used to set the angle value in RotateTransform() for objects drawn in the picture box. What I wanted to do is:

1.If cb1 is check, scrjoint1 is 0.

  • Else scrl1 is whatever the user set it to be.

2.If cb2 is check, scrljoint2 is 0.

  • Else scrljoint2 is whaterver the user set it to be.

3.And so on for the other checkbox and horizontal scroll.

Instead of checking each check box individually and then assigning the value of scrljint respectively, what I had in mind is to achieve by using foreach() function as in the following format:

private void scrJoint_Scroll(object sender, ScrollEventArgs e)
{
    foreach (var cbControl in this.Controls)
    {
        if (cbControl is CheckBox)
        {
            if (((CheckBox)cbControl).Checked)
            {
                //set scrolJoint1~8 = 0 according to checkbox that is checked
            }
            else
            {
                //Do nothing
            }
        }
    }
}

But the current issue I'm having now is,when there is one or more check box that is checked (let say cb1 and cb2 is check) how do I set the respective horizontal scroll bar ( scrJoint1 and scrJoint2 ) to 0 in:

if (((CheckBox)cbControl).Checked)
{
    //set scrolJoint1~8 = 0 according to checkbox that 
}
else
{
    //Do nothing
}

Couple more questions I liked to ask in respect to what I'm trying to do:

1.Is using foreach() a good idea in what I'm trying to achieve?

2.Would it be better if I just check it one by one using If-Else (although I don't want to use this method, because I might need to include more check boxes and scroll bars later, and the code will get ridiculously long very fast).

3.Is there another more cunning ways (clean and short method is preferred) of doing what I wanted to achieve that you guys can suggest (if there is, can you provide an example).

I suppose you are doing right approach. If possible use @Ofir Winegarten suggestion. else wise you can little bit modify your method.and please place proper exception handling as well.

this.Controls.Cast<Control>().Where(row => row.GetType().IsAssignableFrom(typeof(CheckBox)) && ((CheckBox)row).Checked).All(row => SetScroll(((CheckBox)row)));

where setScroll is a method or

foreach (var cbControl in this.Controls.Cast<Control>().Where(row => row.GetType().IsAssignableFrom(typeof(CheckBox)) && ((CheckBox)row).Checked))

A Simple solution might be:

Subscribe to the CheckedChanged event of each of the individual checkboxes.
Inside these methods, set the related scrollbar.Value to 0 and disable it ( scrollBar.Enabled = false ).

private void CbOnCheckedChanged_1(object sender, EventArgs eventArgs)
{
    SetScrollBarValue(this.cb1, this.scrjoint1)
}

private void CbOnCheckedChanged_2(object sender, EventArgs eventArgs)
{
    SetScrollBarValue(this.cb2, this.scrjoint2)
}

....

private static void SetScrollBarValue(CheckBox cb, ScrollBar sb)
{
    if (cb.Checked)
    {
        sb.Value = 0;
        sb.Enabled = false;
    }
    else sb.Enabled = true;
}

You will have the same method of each checkbox.

A more generalized way would be to subscribe to the different checkboxes events with the same method and there, using one of the techniques suggested above, get the related scrollbar. In the following example I chose the shortest one - search by name:

private void CbOnCheckedChanged(object sender, EventArgs eventArgs)
{
    CheckBox cb = (CheckBox) sender;
    ScrollBar sb = (ScrollBar) this.Controls.Find("scrJoint" + cb.Name.Last());
    SetScrollBarValue(cb, sb);
}

Another quite short way is to store the id in the Tag property of each control ( Checkbox and ScrollBar ) and then using linq get the scrollbar:

private void CbOnCheckedChanged(object sender, EventArgs eventArgs)
{
    CheckBox cb = (CheckBox) sender;
    ScrollBar sb = 
        this.Controls.OfType<ScrollBar>().Single(bar => (int)bar.Tag ==(int)cb.Tag);    
    SetScrollBarValue(cb, sb);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM