views:

46

answers:

2

Hi all, I've got six text boxes, and as long as one has valid input in it I want my program to go ahead with import code. Problem is I don't know what the most efficient way to do it is. The two alternatives I've come up with thus far are as follows:

Version 1:

        //if no paths are specified the user is shown an error and the program
        //will do nothing
        if ((txtForecastFTE.Text.Length != 0)
            || (txtActualFTE.Text.Length != 0)
            || (txtForecastAHT.Text.Length != 0)
            || (txtActualAHT.Text.Length != 0)
            || (txtForecastVolume.Text.Length != 0)
            || (txtActualVolume.Text.Length != 0))
        {
            if (txtForecastFTE.Text.Length != 0)
            {
                //import code
            }//end if

            if (txtActualFTE.Text.Length != 0)
            {
                //import code
            }//end if

            if (txtForecastAHT.Text.Length != 0)
            {
                //import code
            }//end if

            if (txtActualAHT.Text.Length != 0)
            {
                //import code
            }//end if

            if (txtForecastVolume.Text.Length != 0)
            {
                //import code
            }//end if

            if (txtActualVolume.Text.Length != 0)
            {
                //import code
            }//end if
        }//end if
        else
        {
            MessageBox.Show("You must enter the path for at least one file.");
        }//end if-else
    }//end import code

Version 2:

        //if no paths are specified the user is shown an error and the program
        //will do nothing
        if (txtForecastFTE.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (txtActualFTE.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (txtForecastAHT.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (txtActualAHT.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (txtForecastVolume.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (txtActualVolume.Text.Length != 0)
        {
    pathTrue = true;
            //import code
        }//end if

        if (!pathTrue)
        {
            MessageBox.Show("You must enter the path for at least one file.");
        }//end if
    }//end import code

Obviously I'll add further validation (try-catch) to each file import section, but this is the basic gist.

Any help appreciated :) If there are other options which would be more efficient than either of the two versions supplied please don't hesitate to put it forward. Thanks guys.

+2  A: 

I'd argue "efficiency" in this case shouldn't be your goal, but rather simple, readable, non-redundant code.

if (this.Controls.OfType<TextBox>().Any(tb => tb.Text.Length > 0))
{
    // get to work
}

Another approach, which might be more fitting upon inspection of your samples, could be

bool hasPath = false;
foreach (TextBox box in this.Controls.OfType<TextBox>().Where(tb => tb.Text.Length > 0))
{
     hasPath = true;
     // import code
}

if (!hasPath)
{
     MessageBox.Show("Need data");
}
Anthony Pegram
`tb.Text.Length` or `tb.TextLength`? Might as well using `string.IsNullOrEmpty()`
PostMan
Right, it's supposed to be tb.Text.Length, didn't type using IDE. Will fix.
Anthony Pegram
Good work without the IDE IMO :)
PostMan
You're right, I misspoke when I said efficiency; non-redundant is really what I wanted to say.This looks perfect but when I try it it won't enter the foreach statement. Debugging shows that it is registering that one text box has text in it, so it should enter and set hasPath to true... EDIT: turns out TextBox box shows as null.
mispecialist
@mispecialist, are the TextBoxes stored inside a container such as a Panel or a TabControl? If so, you'll need to slightly change the code to reference that container. Example: `this.panel1.Controls.OfType<TextBox>()...` (etc.)
Anthony Pegram
Good point, I should have realised the groupbox would change the environment a little. After updating that it works perfectly, thanks Anthony.
mispecialist
A: 

I would suggest you keep those text boxes in the private List<TextBox> variable at initialize time, and do the same thing as Anthony explained.

I am not a fan of Controls property because sometimes your child control is not immediate child of your Form/UserControl (e.g. nested in GroupBox). If you enumerate Controls property for doing some stuff, and later move the control around and place them inside nested container, your code will lose the magic and sometimes it is hard to realize what just happened. Therefore, I prefer identifying them explicitly.

tia