【发布时间】:2012-03-15 09:38:02
【问题描述】:
我正在创建一个自定义服务器控件,以便为我的 Web 窗体应用程序生成带有特定标记和 JavaScript 处理程序的按钮元素。当然,它们能够导致回发,所以我希望它们能够与 ASP 的任何表单验证控件一起工作,尤其是客户端框架。
此按钮服务器控件支持OnClientClick 属性以在按钮标记中使用提供的代码发出onclick 属性(主要用于当用户单击列表视图或类似的删除按钮时的简单确认重新提示) ,因此使用asp:Button 控件将验证脚本作为onclick 属性发出的方法将非常无效。事实上,在标准 asp:Button 上同时指定 OnClientClick 和 ValidationGroup 属性结果非常糟糕。这是一个非常明显的例子,说明为什么它不能开箱即用:
页面标记
<asp:Button ID="btnSaveAsp" ValidationGroup="vgMyValidationGroup" OnClientClick="return true;" runat="server" />
渲染标记
<input type="submit" name="ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp" value="Save" id="cphBodyContent_lvUsers_btnSaveAsp_0"
onclick='return true; WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp", "", true, "vgMyValidationGroup", "", false, false))'>
这是现有的非工作代码,用于通过验证连接控件。除了发出类似的onclick 属性之外,我找不到太多关于如何最好地使用方法完成此操作的文档。我认为我在覆盖的AddAttributesToRender 方法中对Page.ClientSCript.RegisterForEventValidation 的调用将连接客户端验证,但这似乎并没有像我想象的那样起作用。如有必要,可以使用 jQuery 将附加处理绑定到按钮的单击事件:
自定义服务器按钮控件
<ToolboxData("<{0}:Button runat=server></{0}:Button>")> _
<ParseChildren(False)> _
<PersistChildren(True)> _
Public Class Button
Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackDataHandler
Public Sub New()
MyBase.New(HtmlTextWriterTag.Button)
End Sub
<Category("Behavior")> _
<DefaultValue("")> _
Public Overridable Property PostBackUrl As String
Get
Return If(ViewState("PostBackUrl"), String.Empty)
End Get
Set(value As String)
ViewState("PostBackUrl") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue(True)> _
Public Overridable Property CausesValidation As Boolean
Get
Return If(ViewState("CausesValidation"), True)
End Get
Set(value As Boolean)
ViewState("CausesValidation") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue("")> _
Public Overridable Property ValidationGroup As String
Get
Return If(ViewState("ValidationGroup"), String.Empty)
End Get
Set(value As String)
ViewState("ValidationGroup") = value
End Set
End Property
<Category("Behavior")> _
<DefaultValue("")> _
<Description("Client-side script to be run when the button is clicked.")> _
Public Property OnClientClick As String
Get
Return If(ViewState("OnClientClick"), String.Empty)
End Get
Set(value As String)
ViewState("OnClientClick") = value
End Set
End Property
Protected Overrides Sub AddAttributesToRender(writer As HtmlTextWriter)
MyBase.AddAttributesToRender(writer)
If Not String.IsNullOrEmpty(OnClientClick) Then
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, OnClientClick)
End If
Dim postBackOptions = GetPostBackOptions()
If postBackOptions.TargetControl Is Me Then
writer.AddAttribute(HtmlTextWriterAttribute.Name, ClientID)
End If
If Page IsNot Nothing Then
Page.ClientScript.RegisterForEventValidation(postBackOptions)
End If
End Sub
Protected Overridable Function GetPostBackOptions() As PostBackOptions
Dim options As New PostBackOptions(Me) With {
.ClientSubmit = False
}
If Page IsNot Nothing Then
If CausesValidation AndAlso (Page.GetValidators(ValidationGroup).Count > 0) Then
options.PerformValidation = True
options.ValidationGroup = ValidationGroup
End If
If Not String.IsNullOrEmpty(PostBackUrl) Then
options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl))
End If
End If
Return options
End Function
End Class
目前,此代码无法在同一个ValidationGroup 中使用asp:CompareValidator 来确定两个密码重置字段是否相等,然后再发回服务器,也不会在请求到达服务器端后进行验证。
【问题讨论】:
-
您能否举例说明
OnClientClick的实际设置(而不仅仅是return true)? -
return confirm("Are you certain you wish to delete this item"?)或任何其他提示。我实际上已经想出了解决这个问题的方法,我很快就会发布我的解决方案。它涉及对 ASP.NET 回发处理的一些深入研究,但如果我只是将验证添加为 click 事件的侦听器,那么一切都会很好。
标签: asp.net validation webforms custom-server-controls clientscriptmanager