【问题标题】:Alert when cells values are changed in gridview在gridview中更改单元格值时发出警报
【发布时间】:2014-03-04 12:29:45
【问题描述】:

我有一个带有下拉值的网格视图和一个页面中的更新按钮。每当用户更改下拉列表中的任何值并尝试离开页面(分页)时,都会弹出确认警报。如果他们单击“确定”,则必须导航到选定的索引页面,如果单击“取消”,则必须保持在同一页面上。无论如何我可以跟踪更改的单元格值并在用户尝试进行分页或移动到另一个页面而不单击页面中的更新按钮时发出警报。

关于如何实现这一点的任何建议。

【问题讨论】:

    标签: c# asp.net .net gridview


    【解决方案1】:

    您可以使用此链接 here 在 gridview 中添加下拉菜单,并在下拉菜单的更改事件中添加 boolean 值到 viewstate 变量,例如

    ViewState["IsDDChanged"] = true;

    然后您可以注册gridview的PageIndexChanging事件并检查viewstate中的值是否为真,然后您可以使用“RegisterStartupScript”或“RegisterClientScriptBlock”注册一个javascript。关于如何注册 javascript 的链接是 here。

    注册 javascript 后,您可以在同一事件中或通过上述已注册 javascript 的 ajax 调用将 viewstate 设置为 false,具体取决于您的要求。这对于它下次工作很重要。您甚至可以取消分页事件。此链接here

    中给出了该事件和一个很好的例子

    这些可能会给你一个很好的方向。

    希望这会有所帮助。

    编辑:

    我手头有一些时间,所以为您完成了这个小型 POC。 将 aspx 和 aspx.cs 代码复制到一个单独的项目中,并检查这是否是您所需要的

    以下是我遵循的步骤

    1. 创建了RowCreated 事件并使用它添加了下拉列表
    2. 使用PageIndexChanging 事件并使用ScriptManager.RegisterStartupScript 注册了javascript
    3. 添加了一个按钮并将其隐藏
    4. 如果下拉列表已更改且页面已更改,则会弹出确认。如果确认是来自 javascript 的按钮的是调用单击事件,这反过来将为 gridview 进行分页,否则如果下拉列表没有更改,则继续正常分页

    有几点我做过,你需要记住

    1. 在@Page 指令中,我给出了EnableEventValidation="false"。这是必需的,以便我可以触发隐藏按钮的单击事件,但这不是一个好习惯,因为它会降低安全性。对于更安全的方式,您应该使用UpdatePanel of AJAX extensions。
    2. 我使用隐藏按钮的单击事件而不是 JQuery AJAX,因为它需要在代码隐藏中使用静态方法,我们将无法在静态方法中设置 gridview 的分页。否则你需要从 AJAX 调用中发送 gridview 的对象,但这对我来说太麻烦了。
    3. AutoPostBack 到 true 的下拉列表非常重要,否则您的 selectedIndexChanged 事件将不会被触发。即ddlDesignation.AutoPostBack = true;

    aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Grid_Practice.aspx.cs"
        EnableEventValidation="false" Inherits="Practice_Web.Grid_Practice" %>
    
    <!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 id="Head1" runat="server">
        <title></title>
        <script type="text/javascript" language="javascript">
            function ConfirmUser(msg) {
                if (confirm(msg)) {
                    __doPostBack('Button1', 'OnClick');
                }
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server">
        </asp:ScriptManager>
        <div>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" Style="display: none;" />
            <asp:GridView ID="GridView1" runat="server" OnPageIndexChanging="GridView1_PageIndexChanging"
                AllowPaging="true" PageSize="10" AutoGenerateColumns="false" OnRowCreated="GridView1_RowCreated">
                <PagerSettings Mode="NextPreviousFirstLast" FirstPageText="First" LastPageText="Last"
                    NextPageText="Next" PreviousPageText="Prev" Position="TopAndBottom" />
                <Columns>
                    <asp:BoundField />
                </Columns>
            </asp:GridView>
        </div>
        </form>
    </body>
    </html>
    

    aspx.cs

    namespace Practice_Web
    {
        public partial class Grid_Practice : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    //Dummy value for gridview
                    DataTable dt1 = new DataTable();
                    dt1.Columns.Add(new DataColumn("Designation", typeof(String)));
    
                    DataRow dr = null;
                    for (int i = 0; i < 15; i++)
                    {
                        dr = dt1.NewRow();
    
                        dr[0] = "designation" + (i % 2);
                        dt1.Rows.Add(dr);
                    }
    
                    Session["dt"] = dt1;
                    GridView1.DataSource = dt1;
                    GridView1.DataBind();    
                }
    
            }
    
            protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
            {
                Session["NewPageIndex"] = e.NewPageIndex;
                var sessionVar = Session["dropdownChanged"];
                bool dropdownChanged = false;
    
                if (sessionVar != null)
                    dropdownChanged = Convert.ToBoolean(Session["dropdownChanged"]);
    
                if (dropdownChanged)
                {
                    ScriptManager.RegisterStartupScript(this, typeof(string), "Error", "ConfirmUser('Are u sure');", true);
                }
                else
                {
                    ChangeGridPage();
                }
            }
    
            public void ChangeGridPage()
            {
                int pageIndex = Convert.ToInt32(Session["NewPageIndex"]);
                GridView1.PageIndex = pageIndex;
                GridView1.DataSource = (Session["dt"] as DataTable);
                GridView1.DataBind();
            }
    
            protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    DropDownList ddlDesignation = new DropDownList();
                    ddlDesignation.SelectedIndexChanged += new EventHandler(ddlDesignation_SelectedIndexChanged);
                    ddlDesignation.AutoPostBack = true;
    
                    ddlDesignation.ID = "MyID" + e.Row.RowIndex.ToString();
    
                    DataTable dt1 = new DataTable();
                    dt1.Columns.Add(new DataColumn("Designation", typeof(String)));
    
                    DataRow dr = null;
                    dr = dt1.NewRow();
                    dr[0] = "designation0";
                    dt1.Rows.Add(dr);
    
                    dr = dt1.NewRow();
                    dr[0] = "designation1";
                    dt1.Rows.Add(dr);
    
                    ddlDesignation.DataSource = dt1;
                    ddlDesignation.DataTextField = "Designation";
                    ddlDesignation.DataValueField = "Designation";
                    ddlDesignation.DataBind();
                    ddlDesignation.Items.Insert(0, new ListItem("--Select--", "0"));
    
                    ddlDesignation.SelectedValue = (Session["dt"] as DataTable).Rows[e.Row.RowIndex][0].ToString();
    
                    e.Row.Cells[0].Controls.Add(ddlDesignation);
                }
            }
    
            void ddlDesignation_SelectedIndexChanged(object sender, EventArgs e)
            {
                Session["dropdownChanged"] = true;
                //other code here
            }
    
            protected void Button1_Click(object sender, EventArgs e)
            {
                ChangeGridPage();
            }
        }
    }
    

    希望这能解决您的问题

    【讨论】:

    • 不确定我将如何遵循这一点。有点困惑,在哪种情况下我将跟踪 gridview 下拉更改并在分页时显示警报。
    • 对不起,我误解了你的问题。请检查我的更新答案。
    • samar - 我真的很困惑。你能帮我把代码框起来吗?
    • 我建议尝试逐步实施我所说的。如果您遇到困难,只需使用您已实施的任何内容更新您的问题并在我的回答下发表评论。我会进一步指导你。 :)
    • 我在回答中给出了一个小的 POC 代码。将 aspx 和 aspx.cs 代码复制到一个单独的项目中,然后检查是否是您需要的。
    【解决方案2】:

    这似乎是一个很长的答案,但它非常容易应用。

    作为此方案的临时(替代但有效)解决方案,我在MSDN 中找到了这篇关于创建您自己为 GridView 创建 PagerTemplate 的文章。分页器会在 DropDownList 中,它很有趣,并且会更灵活地实现您的要求,为了达到要求,我在代码中稍作修改。

    在您的标记中,将 GridView 修改为如下所示:

    <asp:GridView ID="gridUsers" runat="server"  ShowHeaderWhenEmpty="true" AutoGenerateColumns="False" 
        OnDataBound="CustomersGridView_DataBound"
    HorizontalAlign="Center" Width="100%" AllowPaging="True" >
     <pagerstyle forecolor="Blue"
      backcolor="LightBlue"/>
    
    <PagerTemplate>
      <table width="100%">                    
        <tr>                        
          <td style="width:70%">
    
            <asp:label id="MessageLabel"
              forecolor="Blue"
              text="Select a page:" 
              runat="server"/>
            <asp:dropdownlist id="PageDropDownList"
              onselectedindexchanged="PageDropDownList_SelectedIndexChanged"  
            AutoPostBack="true"              
            onChange="if(!confirm('Continue without saving?! Data will be lost!'))return false;"
             runat="server"/>
          </td>   
    
          <td style="width:70%; text-align:right">
    
            <asp:label id="CurrentPageLabel"
              forecolor="Blue"
              runat="server"/>
          </td>
    
        </tr>                    
      </table>
    
    </PagerTemplate> 
        <Columns>   
        <!-- columns -->
        </Columns>
    
    </asp:GridView> 
    

    接下来,添加如下函数(我用的是VB.Net):

    Protected Sub PageDropDownList_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    
        ' Retrieve the pager row.
        Dim pagerRow As GridViewRow = gridUsers.BottomPagerRow
    
        'Retrieve the PageDropDownList DropDownList from the bottom pager row.
        Dim pageList As DropDownList = DirectCast(pagerRow.Cells(0).FindControl("PageDropDownList"), DropDownList)
    
        ' Set the PageIndex property to display that page selected by the user.
        gridUsers.PageIndex = pageList.SelectedIndex
        SelectData()
    End Sub
    

    最后添加如下函数:

     Protected Sub CustomersGridView_DataBound(ByVal sender As Object, ByVal e As System.EventArgs)
    
            ' Retrieve the pager row.
            Dim pagerRow As GridViewRow = gridUsers.BottomPagerRow
    
            'Retrieve the PageDropDownList DropDownList from the bottom pager row.
            Dim pageList As DropDownList = DirectCast(pagerRow.Cells(0).FindControl("PageDropDownList"), DropDownList)
    
            Dim pageLabel As Label = DirectCast(pagerRow.Cells(0).FindControl("CurrentPageLabel"), Label)
    
            If pageList IsNot Nothing Then
    
                For i As Integer = 0 To gridUsers.PageCount
    
                    Dim pageNumber As Integer = i + 1
                    Dim item As New ListItem(pageNumber.ToString())
    
    
                    If i = gridUsers.PageIndex Then
    
                        item.Selected = True
                    End If
    
                    pageList.Items.Add(item)
                Next
    
            End If
    
            If pageLabel IsNot Nothing Then  
                Dim currentPage As Integer = gridUsers.PageIndex + 1
                pageLabel.Text = "Page " + currentPage.ToString() + " of " + gridUsers.PageCount.ToString()
    
            End If
        End Sub
    

    我确信这不是最好的解决方案,但它很有趣。请注意,我修改了 DropDownList 设计并添加了“OnChange”事件,该事件将执行客户端警报技巧。

    但是,如果用户取消回发,您还需要弄清楚在 DropDownList 中返回旧页码的另一件事,我想您只需创建一个 javascript 函数即可以某种方式实现这一目标。

    希望这会有所帮助。

    【讨论】:

    • 但下拉菜单在 Pagertemplate 中使用,而不是在列中。我该怎么做?
    • 此下拉列表与列中的下拉列表不同。下拉列表是查看页码的另一种方式,而不是网格视图中的默认页码,此下拉列表将包含所有页码和当您单击不同的页码时将在移动到另一个页面之前向您显示警报。这是解决您的问题的另一种方法,因此我建议您先尝试使用 Samar 的答案,因为它似乎是一个更优雅的答案。只需将此答案作为替代解决方案即可。
    猜你喜欢
    • 2018-08-28
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多