Geeks With Blogs

@azamsharp
  • azamsharp The WWDC app says that there are new videos but there is nothing under videos!!! about 412 days ago
  • azamsharp Can I post my opinion on iOS 7 Beta or is it under NDA or something? about 413 days ago
  • azamsharp iOS 7 BETA installed successfully! about 413 days ago
  • azamsharp iOS 7 BETA installed! Now restoring! I am on NET10 which uses AT&T network. Hopefully 3G will still work! Lets c.. about 413 days ago
  • azamsharp The missing of button borders in Xcode 5 makes it hard to determine the clickable area. about 413 days ago
  • azamsharp I might wait for iOS to be released before I can put it on my device! Don't want a bricked or unstable device! about 413 days ago
  • azamsharp Android has many features that no one uses, number of versions that no one upgrades to and thousands of apps that no one pays for. about 413 days ago
  • azamsharp Maybe it is just me but the new iOS 7 UI looks like Windows Phone 8 UI! #maybeIamCrazy about 413 days ago
  • azamsharp Anyone using H20 network upgraded to iOS 7 BETA Keep me updated if you face any problems. about 413 days ago
  • azamsharp @merowing_ You already downloaded it! I cannot even load the developer's website! :( about 413 days ago

AzamSharp Some day I will know everything. I hope that day never comes.

Mark Berseth wrote a very interested article about Bulk Insert Data Using ListView Control. Basically, the ListView control is displayed with the TextBox controls in each row (like MS Excel). Now, the user can write in the TextBox and then use the submit button to insert all the new rows to the database. This works well when you are inserting the data into the database. The problem starts when you try to update the data which is already in the database. Let's say you populate the ListView with some data and now you want to edit it. You will change only one row and press the submit button. The ListView control does not know which row has been changed and hence you will have to send all the rows back to the database even though only a single row got changed.

There should be some way to only update the changed row. In this post I am going to discuss a simple technique that solves this problem. Let's start by populating the GridView control (You can use ListView if you prefer).

 private void BindData()
        {
            string connectionString = "Server=localhost;Database=Northwind;Trusted_Connection=true";
            SqlConnection conn = new SqlConnection(connectionString);
            SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Categories", conn);

            DataSet ds = new DataSet();
            ad.Fill(ds);

            gvCategories.DataSource = ds;
            gvCategories.DataBind();
        }

And here is the HTML view of the GridView control.

<asp:GridView ID="gvCategories" runat="server" DataKeyNames="id" AutoGenerateColumns="false"
            >
   
    <Columns>
   
    <asp:TemplateField HeaderText="CategoryID">
   
    <ItemTemplate>
    <%# Eval("id") %>
    </ItemTemplate>
   
    </asp:TemplateField>
   
       <asp:TemplateField HeaderText="CategoryName">
   
    <ItemTemplate>
    <asp:TextBox ID="txtCategoryName" onchange='<%# AttachFunction(Container.DataItemIndex) %>' runat="server" Text='<%# Eval("CategoryName") %>' />
    </ItemTemplate>
   
    </asp:TemplateField>
   
    <asp:TemplateField HeaderText="Description">
   
    <ItemTemplate>
    <asp:TextBox ID="txtCategoryDescription" onchange='<%# AttachFunction(Container.DataItemIndex) %>' runat="server" Text='<%# Eval("Description") %>' />
    </ItemTemplate>
   
    </asp:TemplateField>
   
    </Columns>
   
    </asp:GridView>

 

I am attaching the onchange JavaScript function to the TextBoxes. The onchange event will be fired whenever the text inside the TextBox will change. I am also passing the current RowIndex of the GridView row. This will keep track which row has been changed. Now, let's check out the AttachFunction which is a server side function.

 protected string AttachFunction(int rowIndex)
        {
            string function = "saveRowIndex(";

            return function + rowIndex + ")";
        }

function saveRowIndex(rowIndex)
{
    AjaxWithJQuery.SimpleService.NoteChangedRows(rowIndex);   
}

In the above code I am firing an Ajax method named NoteChangedRows.

[WebMethod(true)]
        public void NoteChangedRows(int rowIndex)
        {
            List<Int32> list = null;

            if (Session["List"] == null)
            {
                list = new List<int>();

                if (list.Contains(rowIndex)) return;


                list.Add(rowIndex);
                Session["List"] = list;
            }

            else
            {
                list = Session["List"] as List<Int32>;

                if (list.Contains(rowIndex)) return;

                list.Add(rowIndex);
            }

           
        }

NoteChangedRows simply stores the row index of the rows that have been changed. Now, let's see the Update method which is fired when the user clicks the update button.

        protected void Update(object sender, EventArgs e)
        {
            // get only the changed rows and not all the rows
            List<Int32> list = Session["List"] as List<Int32>;

          
            for (int i = 0; i < list.Count; i++)
            {
                GridViewRow row = gvCategories.Rows[list[i]];


                int id = (int) gvCategories.DataKeys[list[i]].Value;
                string categoryName = (row.FindControl("txtCategoryName") as TextBox).Text;
                string categoryDescription = (row.FindControl("txtCategoryDescription") as TextBox).Text;

                // DO THE ACTUAL UPDATE HERE!

                lblFinal.Text += id + "<BR>" + categoryName + "<BR>" + categoryDescription;
            }

            // reset the list!
            Session["List"] = null;
           

        }

The update method simply looks into the RowIndex list and finds the changed rows from that list. Now, we only have to update those changed rows and not all the rows.

I will write an article on this technique and publish it on GridViewGuy. So, stay tunned!

Posted on Thursday, May 22, 2008 11:40 AM | Back to top


Comments on this post: Updating Only Changed Rows Using GridView Control

# re: Updating Only Changed Rows Using GridView Control
Requesting Gravatar...
Azam,

I've been able to use the technique you describe above to handle edits on one of my gridviews, but you need to be aware of a serious error in your code I found out about the hard way. Seemingly you are not alone in this oversite:

Container.DataItemIndex only works if there is no paging on the GridView. If there is, and you've edited a record on any page but the first page, you get an index out of bounds error when you try to use the rowid in your update code because Container.DataItemIndex returns the rowid for the entire datasource, not for the page. If you are using paging, the index needs to be between 0 and the PageSize. The correct value is returned by Container.DisplayIndex in this case.

Regardless, thanks for sharing your code here and at GridViewGuy.
Left by DLT on May 24, 2008 3:13 PM

# re: Updating Only Changed Rows Using GridView Control
Requesting Gravatar...
Hi DLT,

Thanks for super tip! The DisplayIndex works perfectly!
Left by Mohammad Azam on May 25, 2008 4:55 AM

Your comment:
 (will show your gravatar)
 


Copyright © Mohammad Azam | Powered by: GeeksWithBlogs.net | Join free