开发者

Displaying a image in grid view based on condition

开发者 https://www.devze.com 2023-04-04 12:06 出处:网络
I am trying to display 1. Red if the TimeReceived is Null, (or) 2. Amber when Time Received is not null and Time Read is Null (Or)

I am trying to display 1. Red if the TimeReceived is Null, (or) 2. Amber when Time Received is not null and Time Read is Null (Or) 3. Green When Time read is not null

It throws an error

Input string was not in a correct format. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

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

Source Error: 


Line 86:         {
Line 87:             Image img = (Image)e.Row.FindControl("image1");
Line 88:             switch (int.Parse(e.Row.Cells[1].Text))
Line 89:             {
Line 90:                 case 0:

Where I am going wrong, how can I 开发者_如何学Pythondisplay image based on the condition. I think I haven't done the rowdatabound correctly. Please help.


You are probably trying to parse a null or empty string as an int. Change your int.Parse line to:

switch (int.Parse(string.IsNullOrEmpty(e.Row.Cells[1].Text)?"0":e.Row.Cells[1].Text))

UPDATE: Now that you have pasted the actual image of how the Grid looks, I think Joel Etherton is right, you are trying to parse a Date as an integer. Cell[1] (assuming you don't have any invisible columns to the left) is a Date, not an integer so when you try int.Parse throws the exception because it cannot parse it. Also, according to your conditions, your MyGrid_RowDataBound logic is incorrect. Try changing your implementation to this.

protected void MyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        Image img = (Image)e.Row.FindControl("image1");
        //condition for red image; Neither TimeReceived and TimeRead are populated
        if(string.IsNullOrEmpty(e.Row.Cells[1].Text) &&  
           string.IsNullOrEmpty(e.Row.Cells[2].Text))
        {
            img.ImageUrl = "/images/Red.gif";
            img.Visible = true;
        }
        //condition for amber image; TimeReceived not null and TimeRead is null
        else if (!string.IsNullOrEmpty(e.Row.Cells[1].Text) &&  
                 string.IsNullOrEmpty(e.Row.Cells[2].Text))
        {
            img.ImageUrl = "/images/Amber.gif";
            img.Visible = true;
        }
        //condition for green image; TimeReceived not null and TimeRead not null
        else if (!string.IsNullOrEmpty(e.Row.Cells[1].Text) &&  
                 !string.IsNullOrEmpty(e.Row.Cells[2].Text))
        {
           img.ImageUrl = "/images/Green.gif";
           img.Visible = true;
        }
        else //default case
        {
            img.Visible = false;
        }
    }
}


Here's where I see the problem happening, and frankly this piece of code is a bit of a mess.

switch(int.Parse(string.IsNullOrEmpty(e.Row.Cells[1].Text)?"0":e.Row.Cells[1].Text))

There is way too much going on here to be useful. First, e.Row.Cells[1] looks like it's providing a DateTime, so int.Parse is the absolute wrong thing to use here. Based on your description of what you want I don't see how this is going to achieve that in any way.

Here's my stab at it:

Image img = (Image)e.Row.FindControl("image1");

DateTime received;
DateTime read;

DateTime.TryParse(e.Row.Cells[1].Text, received);   // If exception it will produce DateTime.MinValue
DateTime.TryParse(e.Row.Cells[2].Text, read);

if (received == DateTime.MinValue)
{
    img.ImageUrl = "/images/Red.gif";
}
else if (read == DateTime.MinValue)
{
    img.ImageUrl = "/images/Amber.gif";
}
else
{
    img.ImageUrl = "/images/Green.gif";
}

img.Visible = true;

Use if statements when they are appropriate. What you're attempting to do involves dates, so use dates. Simplify your expressions to make them more readable. You don't have to do everything in a single line. The expression passed to your switch statement is doing way too much all in one shot. I'm not saying it's impossible to pull off, but it generates a lot of grey area as to where any generated errors are coming from.


I had difficulty understanding these complicated solutions so I did a little research and here is my solution. I leave it here hoping it help someone

I changed my grid code like this

<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="false" OnRowCommand="RowCommand">
    <Columns>
        <asp:TemplateField HeaderText="Commands">
            <ItemTemplate><asp:ImageButton ID="btnDelete" Visible='<%# ActionPermitted("DELETE") %>' runat="server" ImageUrl="images/bin.png" ToolTip="Delete" CommandName="Delete" CommandArgument='<%# Eval("Id")%>' /></ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="ASPImage">
            <ItemTemplate><asp:Image runat="server" ID="rowImage" ImageUrl='<%# ImageView(((System.Data.DataRowView) Container.DataItem).Row)%>' /></ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="HTMLImage">
            <ItemTemplate><img src='<%# ImageView(((System.Data.DataRowView) Container.DataItem).Row)%>' /></ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="SetVisible">
            <ItemTemplate>
                <img src="green.gif" style='display:<%# Eval("aColumn") == "Value1"? "inline":"none" %>' />
                <img src="red.gif" style='display:<%# Eval("aColumn") == "Value2"? "none":"inline" %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>

In my Code behind I have following functions

protected boolean ActionPermitted(string action){
  return (action=="Delete" || user == "admin");
}

protected string ImageView(DataRow row){
    if (row["SomeData"] == DBNull.Value){
        return "red.gif";
    } else if (row["SomeData"] != DBNull.Value && row["SomeOtherData"] == DBNull.Value){
        return "amber.gif";
    } else {
        return "green.gif";
    }
}

Please note that this is actually 4 different solutions.

  • To change visibility of an asp button based on a value returned from a code behind function (note the single quotes instead of double quotes)
  • To pass current DataRow to code behind and return result based on that
  • To change properties of an HTML tag (can be used to insert data generated in code behind into columns)
  • To show/hide and HTML image (can be any tag)

Last TemplateField is to answer the question.


I agree with Icarus but it would be better if you used int.TryParse instead of int.Parse.

Image img = (Image)e.Row.FindControl("image1");
int val = 0;
int.TryParse(e.Row.Cells[1].Text , out val);
        switch (int.Parse(e.Row.Cells[1].Text))
        {
            case 0:
                img.ImageUrl = "/images/Red.gif";
                img.Visible = true;
                break;
            case 1:
                img.ImageUrl = "/images/Amber.gif";
                img.Visible = true;
                break;
            case 2:
                img.ImageUrl = "/images/Green.gif";
                img.Visible = true;
                break;               
            default:
                img.Visible = false;
                break;
        }
0

精彩评论

暂无评论...
验证码 换一张
取 消