asp .net grid control common gridview operations update edit cancel sort paging

There are many ways to accomplish the end result of what is displayed below.

To display multiple records of data on the same page, you may alternatively use Repeater (my favorite of the dataview controls), DataList or ListView (also great).

FormView and DetailsView are similar, but should be limited to smaller sets of data IMO or in a system where limited results are only displayed in this control after selection from a search or query filter.

The control on the HTML design side:

<asp:UpdatePanel ID="upnlContent" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
            <ContentTemplate>
  <div id="modal" style="display: none;" title="Application Message">
                    <asp:Label ID="lblError" runat="server"></asp:Label>
                </div>
<asp:GridView ID="gvDataList" runat="server" AllowPaging="True" OnRowEditing="gvDataList_EditRecord"
                        OnRowCancelingEdit="gvDataList_CancelRecord" OnRowUpdating="gvDataList_UpdateRecord"
                        AutoGenerateColumns="False" AllowSorting="true" PageSize="50" DataKeyNames="TreeID"
                        OnRowCommand="gvDataList_RowCommand" OnSorting="gvDataList_Sorting" OnPageIndexChanging="gvDataList_PageIndexChanging">
                        <AlternatingRowStyle BackColor="#EFEFEF" />
                        <Columns>
                            <asp:BoundField DataField="TreeID" HeaderText="TreeID" InsertVisible="False" SortExpression="TreeID"
                                ReadOnly="True" />
                            <asp:TemplateField HeaderText="ActiveStatus" SortExpression="ActiveStatus">
                                <ItemTemplate>
                                    <asp:Label ID="lblActiveStatus" runat="server" Text='<%# Eval("ActiveStatus")%>'></asp:Label>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:CheckBox ID="chkActiveStatus" runat="server" Checked='<%# Convert.ToBoolean(Eval("ActiveStatus")) %>'
                                        Enabled='<%# GetEditPermission("activestatus") %>' />
                                </EditItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Name" SortExpression="Name">
                                <ItemTemplate>
                                    <asp:HyperLink ID="Name" runat="server" NavigateUrl='<%# "~/Pages/ExistingOrange.aspx?TreeID=" + Eval("TreeID")%>'>
                        <%# Eval("Name")%>
                                    </asp:HyperLink>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:TextBox ID="tbtreename" runat="server" Text='<%# Eval("Name") %>' />
                                </EditItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Description" SortExpression="Description">
                                <ItemTemplate>
                                    <asp:HyperLink ID="hltreedescription" runat="server" NavigateUrl='<%# "~/Pages/ExistingOrange.aspx?TreeID=" + Eval("TreeID")%>'>
                        <%# Eval("Description")%>
                                    </asp:HyperLink>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:TextBox ID="tbtreedescription" runat="server" Text='<%# Eval("Description") %>' />
                                </EditItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Country" SortExpression="CountryID" ItemStyle-HorizontalAlign="Center">
                                <ItemTemplate>
                                    <asp:Label ID="lblCountryID" runat="server" Text='<%# getcountryname(Eval("CountryID"))%>'></asp:Label>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:DropDownList ID="ddlCountryID" runat="server" Enabled='<%# GetEditPermission("allowregion") %>'
                                        DataSource='<%# countriesdropdown %>' DataTextField='Description' DataValueField="CountryID" />
                                </EditItemTemplate>
                            </asp:TemplateField>
                            <asp:BoundField DataField="LastUpdated" HeaderText="Last Updated" SortExpression="LastUpdated"
                                ReadOnly="true" />
                            <asp:BoundField DataField="ExpirationDate" HeaderText="Expiration Date" InsertVisible="False"
                                SortExpression="ExpirationDate" ReadOnly="True" />
                            <asp:BoundField DataField="runcount" HeaderText="Pick Count" InsertVisible="False"
                                SortExpression="PickCount" ReadOnly="True" />
                            <asp:CommandField ButtonType="Button" EditText="Edit" UpdateText="Update" CancelText="Cancel"
                                HeaderText="Edit Row" ShowEditButton="true" />
                            <asp:ButtonField CommandName="NewOrange" ButtonType="Button" Text="Create" HeaderText="New Orange" />
                        </Columns>
                    </asp:GridView>
            </ContentTemplate>
        </asp:UpdatePanel>

The Events and functions attached to the control on the code behind side:

 private void LoadData(string sort, bool asc)
        {
            DAL.AC_DataClassesDataContext dc = new DAL.AC_DataClassesDataContext();
            var data = (from Trees in dc.Trees
                        join Oranges in dc.Oranges on new { TreeID = Trees.TreeID } equals new { TreeID = Convert.ToInt32(Oranges.TreeID) } into Oranges_join
                        from Oranges in Oranges_join.DefaultIfEmpty()
                        group new { Oranges, Trees } by new
                        {
                            Trees.TreeID,
                            Trees.ActiveStatus,
                            Trees.Name,
                            Trees.Description,
                            Trees.CountryID,
                            Trees.LastUpdated
                        } into g
                        select new
                        {
                            TreeID = (System.Int32?)g.Key.TreeID,
                            ExpirationDate = (System.DateTime?)g.Max(p => p.Oranges.PickDate),
                            PickCount = g.Count(),
                            ActiveStatus = (System.Byte?)g.Key.ActiveStatus,
                            g.Key.Name,
                            g.Key.Description,
                            g.Key.CountryID,
                            LastUpdated = (System.DateTime?)g.Key.LastUpdated
                        });

            data = data.OrderByField(sort, asc); //OrderByField uses dynamic linq library which is a free additional open source download from MS

                try
                {
                    data = data.Where(g => g.TreeID == Convert.ToInt32(ddlTreeIDs.SelectedValue));
                }
                catch (Exception ex)
                {
                    lblError.Text = ex.ToString();
                    utils.ShowJQueryModal(this, ex); //static custom class I created to show dialog containing lblerror text
                }

            gvDataList.DataSource = data;
            gvDataList.DataBind();
            upnlContent.Update();
        }

        protected void gvDataList_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "NewOrange")
            {
                string redirecturl = "~/Pages/NewOrange.aspx?TreeID={0}"; //this page should be pretty self explanatory
                string TreeID = (((GridView)sender).Rows[Convert.ToInt32(e.CommandArgument)].Cells[0]).Text;
                redirecturl = String.Format(redirecturl, TreeID);
                Response.Redirect(redirecturl);
            }
        }

		//example of a mechanism that can be used to change style or visibility of controls specific to user access
        public bool GetEditPermission(string permtype)
        {
            switch (permtype.ToLower())
            {
                case "other":
                    if (utils.usergroup == "admin")
                    {
                        return true;
                    }
                    else return false;
                case "allowregion":
                    if (utils.usergroup == "admin")
                    {
                        return true;
                    }
                    else return false;
                default:
                    return true;
            }
        }

        protected void gvDataList_UpdateRecord(object sender, GridViewUpdateEventArgs e)
        {
            DAL.AC_DataClassesDataContext dc = new DAL.AC_DataClassesDataContext();

            int TreeID, activestatus, CountryID;
            string Name, Description;

            try
            {
                TreeID = Convert.ToInt32(e.Keys[0]); //should be 0
                activestatus = Convert.ToInt32(((CheckBox)gvDataList.Rows[e.RowIndex].FindControl("chkActiveStatus")).Checked);
                Name = Convert.ToString(((TextBox)gvDataList.Rows[e.RowIndex].FindControl("tbName")).Text);
                Description = Convert.ToString(((TextBox)gvDataList.Rows[e.RowIndex].FindControl("tbDescription")).Text);
                CountryID = Convert.ToInt32(((DropDownList)gvDataList.Rows[e.RowIndex].FindControl("ddlCountryID")).SelectedValue);
            }
            catch (Exception ex)
            {
                //throw new Exception("Error retrieving grid values for update.");
                lblError.Text = "Error retrieving grid values for update. Details: " + ex.ToString();
                utils.ShowJQueryModal(this);
                upnlContent.Update();
                return; //unassigned local variables if this is skipped or exception now thrown
            }

            int result = dc.ExecuteCommand("update Trees set ActiveStatus={1}," +
           "Name={2},Description={3}," +
           "CountryID={4} where TreeID={0}",
                      TreeID, activestatus, Name, Description,
                      CountryID);

            if (result == 1)
            {
            }
            else
            {
                lblError.Text = "Record failed to update.";
                utils.ShowJQueryModal(this); //static custom class I created to show modal dialog containing lblerror text
            }
            gvDataList.EditIndex = -1;
            LoadData();
        }

        protected void gvDataList_EditRecord(object sender, GridViewEditEventArgs e)
        {
            gvDataList.EditIndex = e.NewEditIndex;
            LoadData();
        }

        protected void gvDataList_CancelRecord(object sender, GridViewCancelEditEventArgs e)
        {
            gvDataList.EditIndex = -1;
            LoadData();
        }

        private string ConvertSortDirectionToSql(SortDirection sortDirection)
        {
            string newSortDirection = String.Empty;

            switch (sortDirection)
            {
                case SortDirection.Ascending:
                    newSortDirection = "ASC";
                    break;

                case SortDirection.Descending:
                    newSortDirection = "DESC";
                    break;
            }

            return newSortDirection;
        }

        protected void gvDataList_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            gvDataList.PageIndex = e.NewPageIndex;
            gvDataList.DataBind();
        }

        protected void gvDataList_Sorting(object sender, GridViewSortEventArgs e)
        {

            bool asc = true; //default to true per usual .net behavior
            if (ViewState[e.SortExpression] != null)
            {
                asc = (!(bool)ViewState[e.SortExpression]);
                ViewState[e.SortExpression] = asc;
            }
            else
            {
                ViewState[e.SortExpression] = true;
            }

            LoadData(e.SortExpression, asc);
        }

        //Show modal dialog using jquery. Requires javascript reference/link to jquery in the page.
        public static void ShowJQueryModal(Page PageInstance, Exception ex)
        {
            ClientScriptManager ClientScript = PageInstance.ClientScript;
            AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript(PageInstance, PageInstance.GetType(), "preparemodal",
                "<script type=\"text/javascript\">$('#modal').dialog({autoOpen: false, modal: true });</script>", false);
            AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript(PageInstance, PageInstance.GetType(), "loadmodal",
                "<script type=\"text/javascript\">$('#modal').dialog('open');</script>", false);
        }

Links and references to Dynamic LINQ may change over time (no pun intended).

At the time of writing this they can be found on MS and Scott Gu’s blog. If you cannot find it, send me an email and I can send it to you or you can refer to my post on OrderBy Column Name for the exact extension method.

Advertisement

About Ronnie Diaz

Ronnie Diaz is a software engineer and tech consultant. Ronnie started his career in front-end and back-end development for companies in ecommerce, service industries and remote education. This work transitioned from traditional desktop client-server applications through early cloud development. Software included human resource management and service technician workflows, online retail e-commerce and electronic ordering and fulfillment, IVR customer relational systems, and video streaming remote learning SCORM web applications. Hands on server experience and software performance optimization led to creation of a startup business focused on collocated data center services and continued experience with video streaming hardware and software. This led to a career in Amazon Prime Video where Ronnie is currently employed, building software and systems which stream live sports and events for millions of viewers around the world.

Posted on January 9, 2013, in Programming & Development and tagged , , , , , , , , , , , , , , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: