Home > database >  How to convert a GridView string column to an integer or double column?
How to convert a GridView string column to an integer or double column?

Time:12-13

Here is a string column in my GridView:

Convert.ToString(GridView1.Rows[t].Cells[2].Text)

I tried to convert it to double column:

Convert.ToDouble(GridView1.Rows[t].Cells[2].Text)

also tried this:

double x = double.Parse(GridView1.Rows[t].Cells[2].Text)  

but always throws exception: "Input string was not in a correct format"

the code only runs if I type this way Convert.ToString(GridView1.Rows[t].Cells[2].Text)

but there are number values in it and need to get values as a number not a string...

I am using bound field and template field in GridView:

<asp:GridView ID="GridView1" runat="server" Width ="219px" Height="258px">
                    <Columns>
                        <asp:BoundField AccessibleHeaderText="k1" HeaderText="k1" />
                        <asp:BoundField AccessibleHeaderText="k2" HeaderText="k2" />

                        <asp:TemplateField AccessibleHeaderText="Rank1" HeaderText="Rank1">


            <ItemTemplate>
                <asp:Label ID="lblRank" runat="server" ></asp:Label>
            </ItemTemplate>


                        </asp:TemplateField>



                    </Columns>

                </asp:GridView>

Here is the Rank Button code:

protected void Rank_Button_Click(object sender, EventArgs e) {

        SortedDictionary<double, int> MyRank = new SortedDictionary<double, int>();

        foreach (GridViewRow gRow in GridView1.Rows)
        {

            if (Convert.ToDouble(gRow.Cells[0].Text) != 0)
            {

                double score = Convert.ToDouble(gRow.Cells[0].Text);
                while (MyRank.ContainsKey(score))
                    score  = 0.00001;

                MyRank.Add(score, gRow.RowIndex);

                //MyRank.Add(Convert.ToDouble(gRow.Cells[0].Text), gRow.RowIndex);

                gRow.Cells[0].ForeColor = System.Drawing.Color.DarkBlue;
            }
        }


        

        

        for (int irS = 0; irS < GridView1.Rows.Count; irS  )
        {
            if (Convert.ToDouble(GridView1.Rows[irS].Cells[0].Text) > 0)
            {

                ir = ir   1;

            }
        }

        foreach (KeyValuePair<double, int> OneRank in MyRank)
        {


            GridViewRow gRow = GridView1.Rows[OneRank.Value];
            Label lRank = (Label)gRow.FindControl("lblRank");
            lRank.Text = (ir   1).ToString();
            ir--;

        }

This is successfully shows ranking in the template field how you showed me in your example, but:

when template filed uploads with ranking numbers which is this column in Gridview: Convert.ToInt32(GridView1.Rows[t].Cells[2].Text) and I want to access it:

 for (int t = 0; t < GridView1.Rows.Count; t  )
            {
   
                        if (Convert.ToInt32(GridView1.Rows[t].Cells[2].Text) < 5 )
                        {
                            labelX.Text = "message";
                        }
                     }
            
       

it throws exeption : input format is not in correct format...

If I use Convert.ToString(GridView1.Rows[t].Cells[2].Text) format is does not throw exception but cant access the integeres(ranking numbers), if I try to convert it into Convert.ToInt32(GridView1.Rows[t].Cells[2].Text)`

it throws the exception....

CodePudding user response:

Probably the string value in the cell is not a valid representation of a int, the Parse method will throw a FormatException. can you provide us with the value that you are trying to convert?

Try using the TryParse method instead.

var cellValue = GridView1.Rows[t].Cells[2].Text;

if (Int32.TryParse(cellValue, out int intValue))
{
    // If the conversion was successful, use the int value.
    Console.WriteLine(intValue);
}
else
{
    // If the conversion was not successful, handle the error.
    Console.WriteLine("Error: Invalid number format.");
} ```

CodePudding user response:

So, lets MAJOR back up the truck here. We don't have blank values for rank!!

I mean, right off the bat, alarm bells should be going off here in a HUGE HUGE way!!

We see values in the gv for rank.
We observe the code is setting up rank

AND THEN the whole thing is crashing in a MASSIVE ball of flames, since you now seeing "" or empty for the rank. Now we have a bunch of people offing code HOW to deal with blank values WHEN we NEVER are to have blanks!!!

Talk about running down the wrong path!!!

The issue to solve here NOT how to deal with blanks, but discover WHY are we seeing a blank value!!!

Perhaps I am really wasting my time here. I FLAT OUT CRYSTRAL CLEAR stated in my last post this:

for databound columns, you use cells[] to get the value.
for templated columns, you have to use find control.

Now, WHY ARE YOU NOT reading my advice here?

so, trying to pull/use/get/grab the rank value from the cells[] collection WILL NEVER work!!!

if the value from the gv row is in a template column, then we can NOT use the cells collection.

However, lets not use the gv to deal with ranking anyway. It far better to simple avoid this issue.

so, lets assume this markup:

        <asp:GridView ID="GridView1" runat="server" ClientIDMode="Static"
            AutoGenerateColumns="False" DataKeyNames="ID"
            CssClass="table table-hover" Width="50%" ShowHeaderWhenEmpty="true" OnRowDataBound="GridView1_RowDataBound">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName" HeaderStyle-Width="120" />
                <asp:BoundField DataField="City" HeaderText="City" />
                <asp:BoundField DataField="Description" HeaderText="Description" />
                <asp:BoundField DataField="Price" HeaderText="Night Rate" DataFormatString="{0:n2}" />
                <asp:TemplateField HeaderText=" Rank by (Price)">
                    <ItemTemplate>
                        <asp:Label ID="lblRank" runat="server" Text = '<%# Eval("Rank") %>' ></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

And thus we have this code now:

Note HOW we are doing the ranking on the data, and NOT the GV.

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        DataTable rstData = new DataTable();
        rstData = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");

        // now, lets rank the DATA and NOT the GV
        rstData.Columns.Add("Rank", typeof(int));

        var Ranks = new List<KeyValuePair<decimal, int>>();
        int i = 0;
        foreach (DataRow OneRow in rstData.Rows)
        {
            decimal Price = (decimal)OneRow["Price"];
            Ranks.Add(new KeyValuePair<decimal, int>(Price, i));
            i  ;    
        }

        Ranks = Ranks.OrderBy(o => o.Key).ToList(); // sort the list
        decimal LastValue = -1;
        int Rank = 0;
        foreach (KeyValuePair<decimal, int> OneRank in Ranks)
        {
            if (LastValue != OneRank.Key)
                Rank  ;
            rstData.Rows[OneRank.Value]["Rank"] = Rank;
            LastValue = OneRank.Key;
        }

        GridView1.DataSource = rstData;
        GridView1.DataBind();
    }

So, we now see this:

enter image description here

So, note how it was MUCH better to add a "Rank" colum to the data table.

we then run our rank code against the data, and NOT the GV.

Now, say for some reason that we want say the first 5 to be a light blue, and then anything >5 to be a darker blue.

Well, we then would use the row data bound event, and we can do this, and ONCE again, we don't even have to use the gv data, but we can use enjoy the data row value used here. (so, no messy type conversions required!!!).

So, say this code:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DataRowView OneDataRow = (DataRowView)e.Row.DataItem;
            // we can use cells colleciton to fomrat background,
            GridViewRow OneGridRow = e.Row;
            if ((int)OneDataRow["Rank"] <= 5)
                OneGridRow.Cells[6].BackColor = System.Drawing.Color.SkyBlue;
            else
                OneGridRow.Cells[6].BackColor = System.Drawing.Color.SteelBlue;
        }
    }

And now we see/get this:

enter image description here

So the real moral of the story here?

As I stated, we want to try and work with the data, and NOT against the GV.

However, for the sake of learning, lets PULL the rank value from the GV, and in above, the rank value is a templated column, NOT a databound column.

So, remember that rule:

databound columns = cells
tempatled column = we must use find control.

So, our row data bound event to fomrat the column would now become this:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Label MyLableRank = (Label)e.Row.FindControl("lblRank");
            // we can use cells colleciton to fomrat background,
            int MyRank = Convert.ToInt32(MyLableRank.Text);
            if (MyRank  <= 5)
                e.Row.Cells[6].BackColor = System.Drawing.Color.SkyBlue;
            else
                e.Row.Cells[6].BackColor = System.Drawing.Color.SteelBlue;
        }
    }

so, if we are/were/going to/think about/will/entertain the idea of grabbing the value from the gv row? Then above shows how we do this, since as noted, ANY AND ALL templated columns require us to use find control for each row, grab the control type, and then pull the value from the control - we can't use cells collection anymore for such templated columns.

  • Related