-1

I have a simple form which has a few fields which all calculate off each other and are text boxes that require number inputs, I am having an issue where when I submit the form I get the following error even though the text boxes only contain numbers.

Error:

System.FormatException: 'Input string was not in a correct format.'

This exception was originally thrown at this call stack:
    System.Number.StringToNumber(string, System.Globalization.NumberStyles, ref System.Number.NumberBuffer, System.Globalization.NumberFormatInfo, bool)
    System.Number.ParseDecimal(string, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)
    System.Convert.ToDecimal(string)
    CTMS.Fuel.fuelFromTextBox_TextChanged(object, System.EventArgs) in Fuel.cs
    System.Windows.Forms.Control.OnTextChanged(System.EventArgs)
    System.Windows.Forms.TextBoxBase.OnTextChanged(System.EventArgs)
    System.Windows.Forms.Control.Text.set(string)
    System.Windows.Forms.TextBoxBase.Text.set(string)
    System.Windows.Forms.TextBox.Text.set(string)
    CTMS.Fuel.AddFuelButton_Click(object, System.EventArgs) in Fuel.cs
    ...
    [Call Stack Truncated]

From Here:

 private void fuelFromTextBox_TextChanged(object sender, EventArgs e)
    {
        decimal parsedValue;

        if (!decimal.TryParse(fuelToTextBox.Text, out parsedValue))
        {

        }
        else
        {
            mileageMinusTextBox.Text = (Convert.ToDecimal(fuelToTextBox.Text) - Convert.ToDecimal(fuelFromTextBox.Text)).ToString();
        }

        decimal parsedValue2;

        if (!decimal.TryParse(fuelLitersTextBox.Text, out parsedValue2))
        {

        }
        else
        {
            fuelGallonsTextBox.Text = (Convert.ToDecimal(fuelLitersTextBox.Text) / Convert.ToDecimal(convTextBox.Text)).ToString();

        }

        Decimal parsedValue3;

        if (!Decimal.TryParse(fuelGallonsTextBox.Text, out parsedValue3))
        {

        }
        else
        {
            fuelMPGTextBox.Text = Math.Round((Convert.ToDecimal(mileageMinusTextBox.Text) / Convert.ToDecimal(fuelGallonsTextBox.Text)), 3).ToString();
        }

        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
    }

Full Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CTMS
{
public partial class Fuel : Form
{
    public Fuel()
    {
        InitializeComponent();
    }


    private void Fuel_Load(object sender, EventArgs e)
    {
        this.fuelTableAdapter.Fill(this.cTDBDataSet.fuel);
        SqlConnection con = new SqlConnection(Properties.Settings.Default.CTDBCS);
        convTextBox.Text = "4.546";
        con.Open();

        if (con.State == ConnectionState.Open)
        {
            connectedPic.Visible = true;
            disconnectedPic.Visible = false;
            panel1.BackColor = Color.LightGreen;
        }
        else
        {
            connectedPic.Visible = false;
            disconnectedPic.Visible = true;
            panel1.BackColor = Color.OrangeRed;
        }

        string Sql = "SELECT DISTINCT reg FROM vehicles";
        SqlCommand cmd = new SqlCommand(Sql, con);
        SqlDataReader DR = cmd.ExecuteReader();

        while (DR.Read())
        {
            fuelReg.Items.Add(DR[0]);
            fuelReg.SelectedIndex = -1;
            fuelRegView.Items.Add(DR[0]);
            fuelRegView.SelectedIndex = -1;
        }

        con.Close();
        mileageMinusTextBox.Text = "0";
    }


    private void AddFuelButton_Click(object sender, EventArgs e)
    {
        fuelDateTimeCombined.Text = fuelDatePicker.Text + ' ' + fuelTimePicker.Text;
        int currmile; 
        int prevmile;
        Int32.TryParse(fuelToTextBox.Text, out currmile);
        Int32.TryParse(fuelFromTextBox.Text, out prevmile);

        if (string.IsNullOrWhiteSpace(fuelReg.Text) || string.IsNullOrWhiteSpace(fuelFromTextBox.Text) || string.IsNullOrWhiteSpace(fuelLitersTextBox.Text) ||
            currmile < prevmile)


        {
            MessageBox.Show("Values Missing or Mileage less than previous", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        else
        {
            SqlConnection con = new SqlConnection(Properties.Settings.Default.CTDBCS);
            con.Open();
            string Sql = "INSERT INTO fuel (fuelreg, fuelprevmile, fuelcurrentmile, fuellitres, fuelmpg, fueldatetime)"
                        + "VALUES("
                        + "'" + fuelReg.Text + "', "
                        + "'" + fuelFromTextBox.Text + "', "
                        + "'" + fuelToTextBox.Text + "', "
                        + "'" + fuelLitersTextBox.Text + "', "
                        + "'" + fuelMPGTextBox.Text + "', "
                        + "'" + fuelDateTimeCombined.Text + "'"
                        + "); ";
            SqlCommand cmd = new SqlCommand(Sql, con);
            SqlDataReader DR = cmd.ExecuteReader();
            con.Close();

            fuelReg.Text = null;
            fuelFromTextBox.Text = null;
            fuelToTextBox.Text = null;
            fuelLitersTextBox.Text = null;
            fuelMPGTextBox.Text = null;
            fuelDatePicker.Text = null;
            fuelTimePicker.Text = null;
            fuelDateTimeCombined.Text = null;
            this.fuelTableAdapter.Fill(this.cTDBDataSet.fuel);
        }
    }

    private void FuelDateNowButton_Click(object sender, EventArgs e)
    {
        fuelDatePicker.Text = DateTime.Now.ToString();
        fuelTimePicker.Text = DateTime.Now.ToString();

    }

    private void FuelPrevMileage_Click(object sender, EventArgs e)
    {

    }

    private void FuelReg_SelectedIndexChanged(object sender, EventArgs e)
    {

        fuelFromTextBox.ReadOnly = false;
        fuelToTextBox.ReadOnly = false;
        fuelLitersTextBox.ReadOnly = false;

    }

    private void FuelBindingNavigatorSaveItem_Click(object sender, EventArgs e)
    {
        this.Validate();
        this.fuelBindingSource.EndEdit();
        this.tableAdapterManager.UpdateAll(this.cTDBDataSet);

    }

    private void mileageMinusTextBox_TextChanged(object sender, EventArgs e)
    {
        decimal parsedValue2;

        if (!decimal.TryParse(fuelLitersTextBox.Text, out parsedValue2))
        {

        }
        else
        {
            fuelGallonsTextBox.Text = (Convert.ToDecimal(fuelLitersTextBox.Text) / Convert.ToDecimal(convTextBox.Text)).ToString();

        }
        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
    }

    private void FuelLitersTextBox_TextChanged(object sender, EventArgs e)
    {
        decimal parsedValue;

        if (!decimal.TryParse(fuelLitersTextBox.Text, out parsedValue))
        {

        }
        else
        {
            fuelGallonsTextBox.Text = (Convert.ToDecimal(fuelLitersTextBox.Text) / Convert.ToDecimal(convTextBox.Text)).ToString();

        }
        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();

    }



    private void fuelToTextBox_TextChanged(object sender, EventArgs e)
    {
        int parsedValue;

        if (!int.TryParse(fuelToTextBox.Text, out parsedValue))
        {

        }
        else
        {
            mileageMinusTextBox.Text = (Convert.ToDecimal(fuelToTextBox.Text) - Convert.ToDecimal(fuelFromTextBox.Text)).ToString();
        }

        decimal parsedValue2;

        if (!decimal.TryParse(fuelLitersTextBox.Text, out parsedValue2))
        {

        }
        else
        {
            fuelGallonsTextBox.Text = (Convert.ToDecimal(fuelLitersTextBox.Text) / Convert.ToDecimal(convTextBox.Text)).ToString();

        }

        Decimal parsedValue3;

        if (!Decimal.TryParse(fuelGallonsTextBox.Text, out parsedValue3))
        {

        }
        else
        {
            fuelMPGTextBox.Text = Math.Round((Convert.ToDecimal(mileageMinusTextBox.Text) / Convert.ToDecimal(fuelGallonsTextBox.Text)), 3).ToString();
        }
        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
    }

    private void fuelGallonsTextBox_TextChanged(object sender, EventArgs e)
    {
        Decimal parsedValue;

        if (!Decimal.TryParse(fuelGallonsTextBox.Text, out parsedValue))
        {

        }
        else
        {
            fuelMPGTextBox.Text = Math.Round((Convert.ToDecimal(mileageMinusTextBox.Text) / Convert.ToDecimal(fuelGallonsTextBox.Text)),3).ToString();
        }
        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
    }

    private void fuelRegView_SelectedIndexChanged(object sender, EventArgs e)
    {

        BindingSource bs = new BindingSource();
        bs.DataSource = fuelDataGridView.DataSource;
        bs.Filter = "fuelreg like '%" + fuelRegView.Text + "%'";
        fuelDataGridView.DataSource = bs;



    }

    private void tabControl1_Click(object sender, EventArgs e)
    {
        BindingSource bs = new BindingSource();
        bs.DataSource = fuelDataGridView.DataSource;
        bs.Filter = "fuelreg like '%'";
        fuelDataGridView.DataSource = bs;
        fuelRegView.SelectedIndex = -1;
    }

    private void fuelFromTextBox_TextChanged(object sender, EventArgs e)
    {
        decimal parsedValue;

        if (!decimal.TryParse(fuelToTextBox.Text, out parsedValue))
        {

        }
        else
        {
            mileageMinusTextBox.Text = (Convert.ToDecimal(fuelToTextBox.Text) - Convert.ToDecimal(fuelFromTextBox.Text)).ToString();
        }

        decimal parsedValue2;

        if (!decimal.TryParse(fuelLitersTextBox.Text, out parsedValue2))
        {

        }
        else
        {
            fuelGallonsTextBox.Text = (Convert.ToDecimal(fuelLitersTextBox.Text) / Convert.ToDecimal(convTextBox.Text)).ToString();

        }

        Decimal parsedValue3;

        if (!Decimal.TryParse(fuelGallonsTextBox.Text, out parsedValue3))
        {

        }
        else
        {
            fuelMPGTextBox.Text = Math.Round((Convert.ToDecimal(mileageMinusTextBox.Text) / Convert.ToDecimal(fuelGallonsTextBox.Text)), 3).ToString();
        }

        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
    }

}
}
Matt
  • 14,906
  • 27
  • 99
  • 149
  • Where are you getting this error ? – Cid Feb 17 '20 at 10:14
  • 2
    Your query is vulnerable to SQL injections. Consider using [parameterized queries](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=netframework-4.8) – Cid Feb 17 '20 at 10:15
  • 6
    Either `mileageMinusTextBox.Text` or `fuelGallonsTextBox.Text` contain a not-convertible string, so `Convert.ToDecimal` throws. Did you read the **stack trace** of the exception (that tells you exactly _where_ it was thrown)? Did you [debug](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems)? – René Vogt Feb 17 '20 at 10:18
  • @RenéVogt They both contain just a number. Where do i get the stack trace and debug? I i will post them up – Matt Feb 17 '20 at 10:20
  • @Matt To check the values of `mileageMinusTextBox.Text` and `fuelGallonsTextBox.Text`, stick a breakpoint on the first `Int32.TryParse` statement and check what values these have. There may be extra characters that are causing the parsing to fail. – phuzi Feb 17 '20 at 10:26
  • 2
    Why do you actually call `TryParse` and then `Convert.ToDecimal` instead of using `parsedValue`? – René Vogt Feb 17 '20 at 10:27
  • @RenéVogt I am a beginner at C# so this is just what i have put together, how would i use parsedValue instead? – Matt Feb 17 '20 at 10:33
  • 1
    It is rare, but this error message could be thrown also when try to convert input coming from the user with different `cultureinfo`, so you could use `Convert.ToDecimal(String, IFormatProvider)` instead. – Hamed Moghadasi Feb 17 '20 at 10:39
  • @RenéVogt how would i use parsedvalue in my code above – Matt Feb 17 '20 at 22:32
  • @Matt [`TryParse`](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryparse) writes the parsed value into the second argument (`parsedValue` in your first call) if the parsing succeeded. – René Vogt Feb 18 '20 at 09:00
  • @RenéVogt I replaced all my Converts with TryParse and it worked! – Matt Feb 18 '20 at 09:15

1 Answers1

0

Rewritten all the Convert's to use TryParse

private void fuelFromTextBox_TextChanged(object sender, EventArgs e)
    {
        double from, to;
        if (
            !double.TryParse(fuelFromTextBox.Text, out from) ||
            !double.TryParse(fuelToTextBox.Text, out to)
        )
        {

            return;
        }

        mileageMinusTextBox.Text = (to - from).ToString();

        decimal mile, gall;
        if (
            !decimal.TryParse(mileageMinusTextBox.Text, out mile) ||
            !decimal.TryParse(fuelGallonsTextBox.Text, out gall)
        )
        {

            return;
        }

        fuelMPGTextBox.Text = Math.Round((mile / gall), 3).ToString();

        decimal litres, conv;
        if (
            !decimal.TryParse(fuelLitersTextBox.Text, out litres) ||
            !decimal.TryParse(convTextBox.Text, out conv)
        )
        {

            return;
        }

        fuelGallonsTextBox.Text = (litres / conv).ToString();

        fuelFromTextBox.Refresh();
        fuelToTextBox.Refresh();
        fuelLitersTextBox.Refresh();
        fuelGallonsTextBox.Refresh();
        fuelMPGTextBox.Refresh();
        mileageMinusTextBox.Refresh();
        fuelFromTextBox.Update();
        fuelToTextBox.Update();
        fuelLitersTextBox.Update();
        fuelGallonsTextBox.Update();
        fuelMPGTextBox.Update();
        mileageMinusTextBox.Update();
    }
Matt
  • 14,906
  • 27
  • 99
  • 149