简体   繁体   中英

GridView client side paging not working

Work with data from other program (for example in this code i use random number array - like query data from other program). Query it to DataTable and bind to GridView + adds for all rows delete button.

On delete button click - this button is inactive (use button.Enabled = false; and UpdatePanel so on buttons click i have "old" array all works great). But when I use paging - I have "new" array for each time.

How to fix it? I need - in first page i click button - they became inactive, then I choose second page, then return in first page and see "old" array with inactive button.

aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"> 
    <title></title>
    </head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
    <asp:UpdatePanel ID="Up1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowDeleted="GridView1_RowDeleted"
            OnRowDeleting="GridView1_RowDeleting" OnDataBinding="GridView1_DataBinding" AllowPaging="true" PageSize="10" OnPageIndexChanging="GridView1_PageIndexChanging">
            <Columns>
                <asp:BoundField DataField="Name" ItemStyle-Width="200px">
                    <ItemStyle Width="200px"></ItemStyle>
                </asp:BoundField>
                <asp:BoundField DataField="Number" ItemStyle-Width="200px">
                    <ItemStyle Width="200px"></ItemStyle>
                </asp:BoundField>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                            <ContentTemplate>
                                <asp:Button ID="Button2" runat="server" Text="Button" onclick="Button2_Click" OnClientClick="return DeleteConfirm();" />
                                <asp:HiddenField ID="HiddenField2" runat="server" Value='<%# Bind("Name") %>' />

                            </ContentTemplate>
                        </asp:UpdatePanel>
                    </ItemTemplate>
                </asp:TemplateField>



            </Columns>
        </asp:GridView>
        </ContentTemplate>
        </asp:UpdatePanel>
        <br />
        <br />
        <br />
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Reset" />
    </div>
    </form>
    <script type="text/javascript">
        function DeleteConfirm() {
            if (confirm("Are you sure you want to delete this customer from excluded customer list ?")) {
                return true;
            }
            return false;
        }
    </script>
</body>
</html>

aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace WebApplication1
{

        public partial class WebForm1 : System.Web.UI.Page
        {
            private  DataTable _Source;

            public WebForm1()
            {
                ResetData();
            }

            private  void ResetData()
            {
               _Source = new DataTable();
               _Source.Columns.Add("Name", typeof(string));
                _Source.Columns.Add("Number", typeof(string));
                Random rn = new Random();
                for (int t = 0; t < 100; t++)
                {
                    _Source.Rows.Add(rn.Next(1, 10).ToString(), rn.Next(1, 10).ToString());
                }

            }

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

            protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
            {

            }

            protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
            {
                _Source.Rows.RemoveAt(e.RowIndex);
                //GridView1.DataBind();
                Response.Redirect("~/WebForm1.aspx");
            }

            protected void Button1_Click(object sender, EventArgs e)
            {
                ResetData();
                GridView1.DataBind();
            }

            protected void GridView1_DataBinding(object sender, EventArgs e)
            {
                GridView1.DataSource = _Source;
            }

            protected void Button2_Click(object sender, EventArgs e)
            {
                var button = sender as Button;
                button.Enabled = false;
                var hidden = button.Parent.FindControl("HiddenField2") as HiddenField;
                var name = hidden.Value;
                DeletForName(name);
            }

            protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
            {
                GridView1.PageIndex = e.NewPageIndex;
               // GridView1.DataSource = _Source;
                //GridView1.DataBind();

            }
            private  void DeletForName(string name)
            {
                foreach (DataRow row in _Source.Rows)
                    if (row["Name"].Equals(name))
                    {
                      _Source.Rows.Remove(row);
                        break;
                    }
            }
        }
    }

You basically need to store the data source between requests. One option would be to use the Session variable:

public partial class WebForm1 : System.Web.UI.Page
    {
        private DataTable _Source;

        public WebForm1()
        {
        }

        private void ResetData()
        {
            _Source = new DataTable();
            _Source.Columns.Add("Name", typeof(string));
            _Source.Columns.Add("Number", typeof(string));
            Random rn = new Random();
            for (int t = 0; t < 100; t++)
            {
                _Source.Rows.Add(rn.Next(1, 10).ToString(), rn.Next(1, 10).ToString());
            }

            Session["data"] = _Source;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ResetData();
                GridView1.DataBind();
            }
            _Source = Session["data"] as DataTable;
        }

        protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
        {

        }

        protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            ((DataTable)Session["data"]).Rows.RemoveAt(e.RowIndex);
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            ResetData();
            GridView1.DataBind();
        }

        protected void GridView1_DataBinding(object sender, EventArgs e)
        {

            GridView1.DataSource = _Source;
        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            var button = sender as Button;
            button.Enabled = false;
            var hidden = button.Parent.FindControl("HiddenField2") as HiddenField;
            var name = hidden.Value;
            DeletForName(name);
        }

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {

            GridView1.PageIndex = e.NewPageIndex;
            GridView1.DataBind();

        }
        private void DeletForName(string name)
        {

            foreach (DataRow row in _Source.Rows)
                if (row["Name"].Equals(name))
                {
                    _Source.Rows.Remove(row);
                    break;
                }
        }
    }

Basically when the page loads, if it is not a post back, it creates a new DataTable and stores it in the Session variable. If it is a post back, it pulls the already existing data from the Session variable. Also, you only want to call your ResetData function when you need to create a new DataTable , so I took it out of the constructor.

Also, be sure the Name column of your actual data source is unique, because your delete function will delete the first row that has the name you are looking for, not necessarily the row you selected for deletion.

Hope this helps!

EDIT

Two possibilities. I think the most likely is that you want to keep the deleted data in the table, but just mark it as deleted and disable its delete button in the gridview. To do this, my instinct is to add a boolean column to the table that indicates whether a row has been deleted or not. Then when a row is databound, check if it has been deleted and the disable the button accordingly:

private void DeletForName(string name)
{

    foreach (DataRow row in _Source.Rows)
        if (row["Name"].Equals(name))
        {
            row["Deleted"] = true;
            break;
        }
}

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if ((bool)((System.Data.DataRowView)e.Row.DataItem)["Deleted"])
        {
            ((Button)e.Row.FindControl("Button2")).Enabled = false;
        }
    }
}

If you want to remove the item from the table but still disable the button at the index of the rows you have deleted, that would be a little more complicated. Let me know if that's the case and I can try to help with that, but it seems more likely the above is what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM