最正确的为GridView添加删除提示的方法

网上关于这个问题的解决方法,但是都存在一个很严重的问题,那就是:

在弹出提示框“真的要删除”点击“取消”之后,记录还是被删除了......

这个问题的解决方案,有以下几种方法:

方法一(已测试):

首先将按钮那一列转化为模版,然后在其属性里加入下面的js语句,就能弹出一个确认窗口。
<ItemTemplate>
         <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Select"
                            Text="选择" >
       </asp:LinkButton>
        <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Delete" Text="删除"
                 OnClientClick="return confirm( Are you sure you want to delete this record? )" >
       </asp:LinkButton>
</ItemTemplate>

 

方法二(已测试):

按钮类型选择:linkbutton

((LinkButton)e.Row.Cells[1].Controls[0]).Attributes.Add("onclick", " return confirm('你确定要删除吗');")

 

方法三(未测试):

在Page_Load里面先注册一段服务器端脚本:    

if (!Page.ClientScript.IsClientScriptBlockRegistered("deleteConfirmBlock"))
{
            Page.ClientScript.RegisterClientScriptBlock(typeof(string), "deleteConfirmBlock", "function deleteConfirm(){confirm( 确认要删除? );}", true);

}

然后在“删除”按钮的响应函数里面调用这段脚本:

if(Page.ClientScript.IsStartupScriptRegistered("deleteConfirmBlock")){
                Page.ClientScript.RegisterStartupScript(typeof(string), "deleteConfirmBlock","confirmDelete()");
}

//后面的就是删除动作

 

 

 

 

以下是某网友的分析,有兴趣可以看一看:

 

流派甲:

首先将按钮那一列转化为模版,然后在其属性里加入下面的js语句,就能弹出一个确认窗口。
<ItemTemplate>
         <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Select"
                            Text="选择" >
       </asp:LinkButton>
        <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Delete" Text="删除"
                 OnClientClick="return confirm( Are you sure you want to delete this record? )" >
       </asp:LinkButton>
</ItemTemplate>

 

流派乙:

1    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
2    {
3        if (e.Row.RowType == DataControlRowType.DataRow)
4        {
5            ImageButton imgFlag = new ImageButton();
6            imgFlag = ((ImageButton)e.Row.Cells[7].Controls[2]);
7            if (imgFlag.AlternateText == "删除")
8            {
9                imgFlag.Attributes.Add("onclick", "javascript:return confirm( 您确信要删除吗!? )");
10            }
11
12        }
13
14    }

 

流派丙:

在Page_Load里面先注册一段服务器端脚本:    

if (!Page.ClientScript.IsClientScriptBlockRegistered("deleteConfirmBlock"))
{
            Page.ClientScript.RegisterClientScriptBlock(typeof(string), "deleteConfirmBlock", "function deleteConfirm(){confirm( 确认要删除? );}", true);

}

然后在“删除”按钮的响应函数里面调用这段脚本:

if(Page.ClientScript.IsStartupScriptRegistered("deleteConfirmBlock")){
                Page.ClientScript.RegisterStartupScript(typeof(string), "deleteConfirmBlock","confirmDelete()");
}

//后面的就是删除动作

 

流派丁:Response.Write()流派(菜鸟流派)。

清本正源

 

在这里就先将关于按钮的原理先讲清楚,然后再分析上面几种流派到底谁是谁非。

Button渲染原理

其实 ASP.NET 的按钮最后规根结底都会渲染(Render)成HTML的<input ...>控件。根据<asp:Button ...>属性的不同,将渲染成不同的<input ...>控件。而<asp:Button ...>控制这些“不同”的属性就是 UseSubmitBehavior:

UseSubmitBehavior属性值 效果
没有显式设定UseSubmitBehavior的值 默认为true,生成<input type="submit" ... />
true 生成<input type="submit" ... />
false 生成<input type="button" onClick="__doPostBack( XXX ,"XXX")"... />

UseSubmitBehavior为True,渲染后生成<input type="submit" ... /> 的HTML控件。这样的控件在点击的时候将会执行以下动作:
1 执行“onClick”里的Javascript函数
2 执行Form的submit()方法

注意 1中如果onClick内有类似onClick="return confirm( Are you sure you want to delete the row? ); 这样的Javascript代码,Javascript执行的顺序可以用以下代码来类比:

yourButton.onclick=function(){
return confirm( Are you sure you want to delete the row? );
}
form.submit();


你可以看得到,无论你的confirm返回的是true,还是false,form.submit()动作依然会被执行。这就是为什么网上这么多人狂喊“不行啊,我照了你的代码点‘取消’还是删除了”的原因了。
PS:其实这么做,更为可能的后果是出现错误,说“Invalid postback or callback argument ”云云。这是因为回传(PostBack)不是通过正规的__doPostBack("xxx","xxxx")途径来实现的,如果页面上有<%#Page ... EnableEventValidation="true" %>的设定,那么这个错误就会出现。如果将 EnableEventValidation="true" 的值改为“false”,你又会发现页面刷新后根本没有反应......

所以,流派甲可能的最可能的后果是,按【取消】没有问题,而按【确定】则因为回传了非法的回传参数(其实就是空的回传参数),而得到一个错误的页面。(默认情况下,EnableEventValidation="true")

那么我们只有寄希望在UseSubmitBehavior为false的时候了。看看这样有没有搞头。

如果你的按钮的onClick中存在 return confirm( Are you sure you want to delete the row? )这样的代码,那么渲染出来的HTML控件的代码如下:

<input type="button" name="ctl00$ContentPlaceHolder1$GridView1$ctl07$Button1" value="Delete" onclick="return confirm( Are you sure you want to delete the row? );__doPostBack( ctl00$ContentPlaceHolder1$GridView1$ctl07$Button1 , )" id="ctl00_ContentPlaceHolder1_GridView1_ctl07_Button1" />

那么它的Javascript执行顺序是:
1 return confirm( 确定要删除? );
2 __doPostBack( ctl00$ContentPlaceHolder1$GridView1$ctl07$Button1 , );

__doPostBack其实是一个在每一个页面开始不久处定义的Javascript函数。HTML的控件是没有状态的,而ASP.NET的大部分控件是有的。在这个“有”和“没有”之间嫁接其桥梁,就是这个函数:

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms[ aspnetForm ];
if (!theForm) {
    theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>

也许你已经注意到,上述中的Javascript执行顺序有问题,它等同于以下代码:

$Button1.onclick=function(){
return confirm( Are you sure you want to delete the row?    );
__doPostBack( ctl00$ContentPlaceHolder1$GridView1$ctl07$Button1 , );

}

我们可以发现一些东西:
1 原来我们在.aspx页面标签中的写的OnClientClick=“XXXX;”,最后会被包装成“XXXX;__doPostBack("xxx","xxxx")”;(注意,要在UseSubmitBehavior为false的情况下)
2 语句“ return confirm( Are you sure you want to delete the row?    );”后的“__doPostBack”永远也不会得到执行,因为return;

我们写的Javascript语句将会被首先执行,然后才是__doPostBack。那么我们的代码应该这样写:

<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="if (confirm( Are you sure you want to delete the row? )==false) {return false;}" UseSubmitBehavior="False" />

然后输出正确HTML:

<input type="button" name="Button1" value="Button" onclick="if (confirm( Are you sure you want to delete the row? )==false) {return false;};__doPostBack( XXXXX , XXXXX )" id="Button1" />  


//注意 XXXX 代表ASP.NET自动生成的、对于要说明的问题无关紧要的、省略的内容

执行的Javascript就是:

Button1.onclick=function(){
if (confirm( Are you sure you want to delete the row?    )==false)return;
__doPostBack( ctl00$ContentPlaceHolder1$GridView1$ctl07$Button1 , );

}

这才是我们要的结果!所有流派甲并不能满足我们的要求。

posted @ 2010-11-28 23:11  谢多  阅读(386)  评论(0)    收藏  举报