[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 334
  • Last Modified:

GridView Customization

Hello Experts,

I would like to add an image called CheckImage.png to a field labeled pldg_complete if the field has a value of 1.

If it has a value of 0 then I would like to display an image called NoCheckImage.png for that row in the GridView Control.

Is this possible and if so how?

Please see my CodeBehind for retrieving the data to the GridView Control.


protected void RetrieveAllPledgeParticipants()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessChoice"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "WellnessChoiceAdmin_RetrieveAllPledgeParticipants";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            DataTable dtPledgeParticipants = new DataTable();
            SqlDataAdapter adp = new SqlDataAdapter();

            try
            {
                conn.Open();

                adp.SelectCommand = cmd;
                adp.Fill(dtPledgeParticipants);

                gv_Pledge.DataSource = dtPledgeParticipants;
                gv_Pledge.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
    }

Open in new window

0
asp_net2
Asked:
asp_net2
  • 14
  • 12
  • 4
1 Solution
 
Seven priceFull StackCommented:
In grid view you can try a rowDatabound and for example

  If btn IsNot Nothing Then
                    If String.IsNullOrEmpty(btn.ImageUrl) Then
                        btn.ImageUrl = "image.gif"
else
                        btn.ImageUrl = NoCheckImage.png"
                    End If
                End If
0
 
asp_net2Author Commented:
Not sure I understand what you mean :( I have all data getting retrieved on Page_Load.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
asp_net2Author Commented:
I still don't understand how to add the image based on the value for that field. Nor did I understand the link you sent. I already saw that link before posting here.
0
 
Seven priceFull StackCommented:
Ok give me a sec i will try to show you.
0
 
Seven priceFull StackCommented:
sorry i just got real busy but try this link and let me know if this works.

http://forums.asp.net/t/1169201.aspx/1
0
 
asp_net2Author Commented:
Hi sevensnake77,

No, I don't understand what I need to do or how to set this up. I have searched for help on google for this issue and could not find anything useful or at least that I could understand which is why I'm hear asking for help.
0
 
ddayx10Commented:
The gridview control has an event called rowdatabound. This is the event you will use to look at each individual row and make a decision about the value of pldg_complete. In this event after you have looked at pldg_complete and made a distinction between 0 or 1 then you have to find the control in that row that needs its image changed.

A more specifically meaningful example cannot be created for you without seeing the code for your gridview. If you post the code for your gridview maybe one of the others will elaborate. If they dont I will (I dont want to steal their points if they are willing to show you).
0
 
asp_net2Author Commented:
@ddayx10,

Thank you for the offer!! I have attached my GridView Markup.

Thanks in advance!!!
<asp:GridView ID="gv_Pledge" runat="server" AutoGenerateColumns="False" 
                    Width="600px" OnRowDataBound="gv_Pledge_RowDataBound">
                    <Columns>
                        <asp:BoundField DataField="pi_id">
                        <HeaderStyle CssClass="label" HorizontalAlign="Left" />
                        <ItemStyle CssClass="gridviewlabel" />
                        </asp:BoundField>
                        <asp:BoundField DataField="pi_fname" HeaderText="First Name">
                        <HeaderStyle CssClass="label" HorizontalAlign="Left" />
                        <ItemStyle CssClass="gridviewlabel" />
                        </asp:BoundField>
                        <asp:BoundField DataField="pi_lname" HeaderText="Last Name">
                        <HeaderStyle CssClass="label" HorizontalAlign="Left" />
                        <ItemStyle CssClass="gridviewlabel" />
                        </asp:BoundField>
                        <asp:BoundField DataField="pldg_date" DataFormatString="{0:d}" 
                            HeaderText="Date Completed">
                        <HeaderStyle CssClass="label" HorizontalAlign="Left" />
                        <ItemStyle CssClass="gridviewlabel" />
                        </asp:BoundField>
                        <asp:BoundField DataField="pldg_complete" HeaderText="Status">
                        <HeaderStyle CssClass="label" HorizontalAlign="Left" />
                        <ItemStyle CssClass="gridviewlabel" />
                        </asp:BoundField>
                    </Columns>
                    <EmptyDataTemplate>
                        <asp:ImageButton ID="ImageButton1" runat="server" />
                    </EmptyDataTemplate>
                </asp:GridView>

Open in new window

0
 
asp_net2Author Commented:
@ddayx10,

Please note: I did add the OnRowDataBound="gv_Pledge_RowDataBound" to the GridView Above in the Markup but DO NOT have any code associated to it since I don't know what to do. I initially added it when sevensnake77 told me that I needed it but I did not understand his sample or tutorials he supplied links to. I also searched google for what I need and was unable to find what I'm dealing with.
0
 
ddayx10Commented:
Ok so note I added a templatefield to your gridview. We cant add an image and modify it to an asp:Boundfield.

In the templatefield I added a label so you could see your pldg_complete value and I added an asp:Image.

In the rowdatabound event I find the image, check the value of pldg_complete and set a src for the image based on this value.

Once you understand how this works you may want to remove your old boundfield for pldg_complete and the label I have put in the templatefield. You may want to change it around completely but this should give you the concept for how to do what you are asking.

Ah what the heck I'll throw in the dog .png's too :)
***ASPX PAGE****
    <asp:GridView ID="gv_Pledge" runat="server" AutoGenerateColumns="False" Width="600px" OnRowDataBound="gv_Pledge_RowDataBound">
        <Columns>
            <asp:BoundField DataField="pi_id">
            <HeaderStyle CssClass="label" HorizontalAlign="Left" />
            <ItemStyle CssClass="gridviewlabel" />
            </asp:BoundField>
            <asp:BoundField DataField="pi_fname" HeaderText="First Name">
            <HeaderStyle CssClass="label" HorizontalAlign="Left" />
            <ItemStyle CssClass="gridviewlabel" />
            </asp:BoundField>
            <asp:BoundField DataField="pi_lname" HeaderText="Last Name">
            <HeaderStyle CssClass="label" HorizontalAlign="Left" />
            <ItemStyle CssClass="gridviewlabel" />
            </asp:BoundField>
            <asp:BoundField DataField="pldg_date" DataFormatString="{0:d}" 
                HeaderText="Date Completed">
            <HeaderStyle CssClass="label" HorizontalAlign="Left" />
            <ItemStyle CssClass="gridviewlabel" />
            </asp:BoundField>
            <asp:BoundField DataField="pldg_complete" HeaderText="Status">
            <HeaderStyle CssClass="label" HorizontalAlign="Left" />
            <ItemStyle CssClass="gridviewlabel" />
            </asp:BoundField>
            <asp:TemplateField HeaderText="Status W Image">
				<ItemTemplate>
					<asp:Label ID="LbPldg_Complete" runat="server" Text='<%#Bind("pldg_complete") %>' />
					<asp:Image ID="ImgDynamic" runat="server" ImageUrl="" Height="49px" Width="49px" />
				</ItemTemplate>
            </asp:TemplateField>
        </Columns>
        <EmptyDataTemplate>
            <asp:ImageButton ID="ImageButton1" runat="server" />
        </EmptyDataTemplate>
    </asp:GridView>

Open in new window

****CODE BEHIND ROWDATABOUND EVENT****
    //fires for every row that's been bound in gridview
    protected void gv_Pledge_RowDataBound(Object sender, GridViewRowEventArgs e)
    {
        //check if its a data row (not footer or header for example)
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //find image in our itemtemplate
            Image img = (Image)e.Row.FindControl("ImgDynamic");

            //get the column value we want to check against (0 or 1)
            string pldg_complete = (string)DataBinder.Eval(e.Row.DataItem, "pldg_complete");

            //set our img src based on pldg_complete value (0 or 1)
            if (pldg_complete == "0")
            {
                img.ImageUrl = "img/dog.png";
            }
            else
            {
                img.ImageUrl = "img/nodog.png";
            }
        }

    }

Open in new window

dog.png
nodog.png
0
 
ddayx10Commented:
NOTE:

In this line:
            //get the column value we want to check against (0 or 1)
            string pldg_complete = (string)DataBinder.Eval(e.Row.DataItem, "pldg_complete");


I used a string emulating my datatype as maybe a varchar but your datatype may be an int or something and you will have to adjust as necessary and also in if statement below.
0
 
asp_net2Author Commented:
@ddayx10,

Ok, I added your code and made a change to the pldg_complete field since its an int type and not a string. When I run my code I only see one returned row and before I added you code I was getting around 200 + returned rows of data. Not sure if this matters but I have all data returned to a DataTable. Also, is there a way to handle which image to display within the RetrieveAllPledgeParticipants() Event Handler Code rather than using the RowDataBound? Please see attached updated code using your method.


protected void Page_Load(object sender, EventArgs e)
    {
        RetrieveAllPledgeParticipants();
    }

    protected void gv_Pledge_RowDataBound(Object sender, GridViewRowEventArgs e)
    {
        //check if its a data row (not footer or header for example)
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //find image in our itemtemplate
            Image img = (Image)e.Row.FindControl("ImgDynamic");

            //get the column value we want to check against (0 or 1)
            int pldg_complete = (Int32)DataBinder.Eval(e.Row.DataItem, "pldg_complete");

            //set our img src based on pldg_complete value (0 or 1)
            if (pldg_complete == 1)
            {
                img.ImageUrl = "../images/complete.png";
            }
            else
            {
                img.ImageUrl = "../images/not_complete.png";
            }
        }
    }

    protected void RetrieveAllPledgeParticipants()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessChoice"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "WellnessChoiceAdmin_RetrieveAllPledgeParticipants";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            DataTable dtPledgeParticipants = new DataTable();
            SqlDataAdapter adp = new SqlDataAdapter();

            try
            {
                conn.Open();

                adp.SelectCommand = cmd;
                adp.Fill(dtPledgeParticipants);

                gv_Pledge.DataSource = dtPledgeParticipants;
                gv_Pledge.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
    }

Open in new window

0
 
asp_net2Author Commented:
@ddayx10,

Ok, so I removed your RowDataBound Even Handler Code and modified the GridView Control to not fire that Event and modified my original code below. When I run the code I see a column for the image and it's displaying a broken Image URL. Any idea why it's not showing the images?


protected void RetrieveAllPledgeParticipants()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessChoice"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "WellnessChoiceAdmin_RetrieveAllPledgeParticipants";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            DataTable dtPledgeParticipants = new DataTable();
            SqlDataAdapter adp = new SqlDataAdapter();

            try
            {
                conn.Open();

                adp.SelectCommand = cmd;
                adp.Fill(dtPledgeParticipants);

                Image img = new Image();

                if (dtPledgeParticipants != null)
                {
                    DataRow data = dtPledgeParticipants.Rows[0];

                    if (data["pldg_complete"] == "1")
                    {
                        img.ImageUrl = "../../images/complete.png";
                    }
                    else
                    {
                        img.ImageUrl = "../../images/complete.png";
                    }                  
                }

                gv_Pledge.DataSource = dtPledgeParticipants;
                gv_Pledge.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
    }

Open in new window

0
 
ddayx10Commented:
The way you had it the first time is correct (37035839) the second way you posted it is not good at all (37035891).

The code we added for the onrowdatabound will have nothing to do with how many rows display. That is all controlled by your RetrieveAllPledgeParticipants function (which you already know).

You cannot in any way affect the image properly from the RetrieveAllPledgeParticipants function.
0
 
ddayx10Commented:
Have you debugged and checked if you are having an exception somewhere?

you could try changing ex.Message.ToString(); to be:

Response.Write(ex.Message.ToString());

This way if there is an error you will get some indication.
0
 
ddayx10Commented:
Using the same code I gave you and a db that was setup to emulate your table schema I get it to work just fine <see image>.

The problem is in your data, or your pulling of the data. BTW programmers debugging mantra #37 = "It worked before therefore it should work now is faulty logic."

The way you are connecting with your grid using an adapter? Well I wouldn't bother I'd do it more like this (see snippet).
protected void RetrieveAllPledgeParticipants()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WellnessChoice"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("WellnessChoiceAdmin_RetrieveAllPledgeParticipants",conn);
            cmd.CommandType = CommandType.StoredProcedure;
            try
            {
                conn.Open();
                gv_Pledge.DataSource = cmd.ExecuteReader();
                gv_Pledge.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
    }

Open in new window

crazygrid.jpg
0
 
asp_net2Author Commented:
Hi ddayx10,

Ok, I change my code back to how it was (37035839) and I also added Response.Write(ex.Message.ToString()); and when I run the code I get the following message from Response.Write. Not sure what that means.

Error Message:
Specified cast is not valid.
0
 
asp_net2Author Commented:
Hi ddayx10,

I believe you, I just can't figure out why it's not working for me. I also made the change to the code an just used SqlDataReader but I still get the same results.
0
 
ddayx10Commented:
I know its dumb but have you checked the data to make sure some process didnt delete it.

Go into sql and run the stored proc and make sure its returning all rows. I mean if its just SELECT * FROM tblName then its probably fine, but if there's a where clause for a date range or something??

Did you make some sort of syntax error in the GridView causing it not to render properly?

Ahhhh.... anyway I know its frustrating but dont overlook anything obvious, make no assumptions because its probably something simple.
0
 
ddayx10Commented:
Ahhh I just saw your note above (37035958). Its telling you that your casting of pldg_complete is not correct. It is not able to cast from whatever type in your database to an Int32 most likely.
0
 
asp_net2Author Commented:
Hi ddayx10,

Yes, that was the first thing I did :) I executed the SP and it returned all 200 + rows. Also, I fixeed the one error "Specified cast is not valid" but now I have another error :( that says "Object cannot be cast from DBNull to other types." The only thing I can think of is that the pldg_date field WILL contain NULL values for the rows that contain the value 0 for field dg_complete.

The "specified cast is not valid" was on line below. Below is the correction I made.

Before:
int pldg_complete = (int)DataBinder.Eval(e.Row.DataItem, "pldg_complete"));

After:
int pldg_complete = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "pldg_complete"));
0
 
asp_net2Author Commented:
Oh, crap, I just saw that pldg_complete DOES contain some NULL values. So I was wrong then, pldg_complete will either contain NULL or 1 :(
0
 
ddayx10Commented:
what type is it? bit or varchar or int or bigint or ??
0
 
asp_net2Author Commented:
pldg_complete is int.
0
 
ddayx10Commented:
Took me so long because I was trying to deal with Int32? to make it nullable but I finally gave up....you should be able to change to this <see snippet>.

If at all possible I would consider setting a default value of 0 in my database table and filling in the blanks. Null values are just a pain in the long run and in my opinion to be avoided.
//fires for every row that's been bound in gridview
    protected void gv_Pledge_RowDataBound(Object sender, GridViewRowEventArgs e)
    {
        //check if its a data row (not footer or header for example)
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //find image in our itemtemplate
            Image img = (Image)e.Row.FindControl("ImgDynamic");

            Int32 pldg_complete = 0;

            if (DataBinder.Eval(e.Row.DataItem, "pldg_complete") != DBNull.Value)
            {
                //get the column value we want to check against (0 or 1)
                pldg_complete = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "pldg_complete"));
            }

            //set our img src based on pldg_complete value (0 or 1)
            if (pldg_complete == 1)
            {
                img.ImageUrl = "img/dog.png";
            }
            else
            {
                img.ImageUrl = "img/nodog.png";
            }
        }

    }

Open in new window

0
 
asp_net2Author Commented:
@ddayx10,

That worked. Thank you. Now what would I need to change if I was dealing with a 0 rather than NULL?
0
 
ddayx10Commented:
Nothing. It will work with 0, 1 or Null as is.

The variable is initially set to 0

If the db.value is null that variable doesnt change and its what we're using in our if statement later

If db.value is not null it will be assigned to the variable (Int32 pldg_complete) so it will be 0 or 1

This code will work whether you change or not.

Im going to bed :)

Im glad you got it working.
0
 
ddayx10Commented:
sooo

null = 0
0 = 0
1 = 1

hope that makes sense...now sleep
0
 
asp_net2Author Commented:
Thank you ddayx10!!! I appreciate all your help. Yes, going to sleep now :)
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

  • 14
  • 12
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now