-1

I would like my application to to check if all 5 textboxes are numeric, and if the values are all true. Display the Talley. If not, I don't want my method to execute and right now it is. The way I have IsValid method coded, to me seems like it should work. I guess if someone could point me in the right direction, I'm sure there is a simple way of doing something such as this but I haven't found it. Thanks in advance to anyway that takes their time to look at this.

I have tried several variations of the example here, but haven't been able to do what it needs to do.

      private void btnCalculate_Click(object sender, EventArgs e)
    {


        if (IsValid()) // if everything passes it will hit this
        {
            double total;
            double hospitalCharge;
            hospitalCharge = CalcStayCharges() * Convert.ToDouble(txtDays.Text);
            total = hospitalCharge + CalcMiscCharges();
            CalcTotalCharges(total);
            lblDisplay.Text = "The total is " + CalcTotalCharges(total).ToString("c");
        }

        //else return;

        // IsNumber(txtDays.Text.ToString()); // testing somehing 

    }

    private double CalcStayCharges()
    {
        double hosipalCharge = 350;
        return hosipalCharge;
    }

    private double CalcMiscCharges()
    {
        double Totalcharges;
        Totalcharges = Convert.ToDouble(txtLab.Text) + Convert.ToDouble(txtMedication.Text) + Convert.ToDouble(txtRehab.Text) + Convert.ToDouble(txtSurgical.Text);
        return Totalcharges;
    }

    private double CalcTotalCharges(double total)
    {
        return total;
    }
    private bool IsNumber(TextBox myNumber)
    {
        if (double.TryParse(Convert.ToString(myNumber), out double n))
        {
           // MessageBox.Show("string");
            return false;

        }
       // MessageBox.Show("number"); // this is how you can test a bool value
        return true; 
    }
    private bool IsValid()
    {
        bool validation = false;
        foreach (Control ctl in this.Controls)
        {
            if (ctl is TextBox)
            {
                TextBox tb = ctl as TextBox;
                IsNumber(tb); 
                if (IsNumber(tb) == true)
                {
                    validation = true;

                }
                else if (IsNumber(tb) == false)
                {
                    validation = false;
                }

            } 

        }
        return validation;

    }
  • Your `IsValid` function can be greatly condensed. Change the `if` to: `if (ctl is TextBox tb) {if (!IsNumber(tb) {return false;}}' Then, after the loop: `return true;` (I think I have that right). Use a pattern-matching `if`, then if `IsNumber` fails for any of the controls, return false. If you get to the end of the loop, then return true. – Flydog57 Jan 10 '19 at 21:27
  • In addition to the answers posted, I think maybe your code that checks for a number needs to return true for if (double.TryParse(Convert.ToString(myNumber), out double n)) and false if it doesn't parse (the opposite of what you have) – Nikki9696 Jan 10 '19 at 21:27

5 Answers5

0

The problem is that your loop will override validation with whatever value it has last. So, as it stands, you code will only really validate the last text box.

The usual way to handle this is to make an assumption that it is valid. Loop through everything, and only set it if it is invalid. like this.

private bool IsValid()
{
    bool validation = true;
    foreach (Control ctl in this.Controls)
    {
        if (ctl is TextBox)
        {
            TextBox tb = ctl as TextBox;
            IsNumber(tb); 
            if (IsNumber(tb) == false)
            {
                validation = false;
            }

        } 

    }
    return validation;

}
Matti Price
  • 3,351
  • 15
  • 28
0

I rephrased your IsValid statement. Please check it out

private bool IsValid()
{
    bool validation = true;
    foreach (Control ctl in this.Controls)
    {
        if (ctl is TextBox)
        {
            TextBox tb = ctl as TextBox;
            if (IsNumber(tb) == false)
            {
                validation = false;
                break;
            }

        } 

    }
    return validation;

}

Improved version (basic syntax)

private bool IsValid()
{
    bool validation = true;
    foreach (TextBox tb in this.Controls.OfType<TextBox>())
    {
        if (!IsNumber(tb))
        {
            validation = false;
            break;
        }
    }
    return validation;

}
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72
0

Nick, please check this answer and you will understand. Basically he is getting all controls from the Page of type DropDownList (in your case TextBox). And then he iterates each control and validates them. If you want something more complex, when iterating the list of controls, you can validate its properties and process the controls with the specified properties that you gave to them, when you declared them in the page.

Hugo Barona
  • 1,303
  • 9
  • 21
0

Another variation of IsValid. It uses a pattern matching if and plays logic games to get rid of the validation variable:

 private bool IsValid()
 {
     foreach (var control in this.Controls)
     {
         if (control is TextBox textBox)
         {
             //the first test to fail cause the function to return false
             //no need to test the rest of the controls
             if (!IsNumber(textBox))
             {
                 return false;
             }
         }
     }
     //nothing returned false, so it must be valid
     return true;
 }

Notice that true and false only appear in the return statements. You don't need to test Booleans for truthiness or falsehood, they are true or false all on their own. If you want to test a bool b for true-ness:

if (b) { /* code goes here */ }

of for false-ness

if (!b) { /* other code */ }

The other thing you might do if you have a lot of controls on the page and only a few of them are text boxes is keep a separate collection of textbox controls. You could have a List<TextBox> and populate it once at page load time.

Flydog57
  • 6,851
  • 2
  • 17
  • 18
0

Why for-each? :) use Linq (more declarative way) programming! More of a condensed form and readable.

private bool IsValid()
    {
        return this.Controls.OfType<TextBox>().Where(t => 
                IsNumber(t.Text)).ToList().Any();
    }

You can use your IsNumber(...) to validate the text box values.

So you can use the validate method as below

if (!IsValid()) return;

Hope this helps.

Cheers!

RSF
  • 510
  • 6
  • 18