×××××××(300分问题)自定义WEB控件,如何才能真正解决“在非窗体控件中保持客户端更改”问题?×××××××

junglerover 2004-12-26 01:40:55
本人初学.Net,正在做一个“表格编辑”的自定义Web控件。现在客户端功能都已实现,也参考了MSDN中的“在非窗体控件中保持客户端更改”章节,只要在Web页上的Form提交之前,执行一个我自己的Javascript函数SaveData,就能将客户端对表格的编辑写入隐藏域,然后上传回服务器端。

现在的问题是:如何能保证,该WEB页每次被上传时,都能调用我的SaveData函数?我不可能在表格内容每次被编辑的时候都调用SaveData函数,因为表格行数可能很多,每次更改时都调用SaveData会极大地降低客户端的运行效率。这里就和MSDN中“在非窗体控件中保持客户端更改”章节所举的例子不同,它的控件很简单,每次客户端做修改时,都直接更新隐藏域的值。

我已经尝试过在控件OnInit时调用Page.RegisterOnSubmitStatement,但是我发现这个方法是没有意义的,它只是简单地把你要调用的Script代码写入Form的OnSubmit事件,而众所周知的是,Form.Submit并不触发OnSubmit事件。

例如,你在页面上放一个Calendar,它点击任何日期时都会提交,但是,不会触发Form的Onsubmit事件,使用Page.RegisterOnSubmitStatement写入的客户端代码也不会被调用。

我现在的做法是:使用Page.RegisterStartupScript,自己写一个__doPostBack ,强行覆盖掉由页框架自动生成的__doPostBack(eventTarget, eventArgument)方法,在这个方法里面执行SaveData 。其实也没有真正覆盖掉,只是在最后生成的页面HTML代码中会有2个同名的JAVASCRIPT方法而已。因为我的方法比原有的__doPostBack后生成,最后的效果好像是__doPostBack被我重载掉了。

这样做虽然暂时可以解决问题,但是我认为它是不完善的。比如,有没有办法,直接改掉由页框架自动生成的__doPostBack代码?

如能解决该问题,将给出300分,绝不食言。帮顶有分!
...全文
200 点赞 收藏 27
写回复
27 条回复
junglerover 2005年01月19日
再UP一下,没结果的话,今晚就结帖了。
回复 点赞
junglerover 2005年01月19日
最后一下!想帮顶接分的快来,最后机会了啊
回复 点赞
junglerover 2005年01月17日
再UP一下!
回复 点赞
junglerover 2005年01月14日
up
回复 点赞
kenMoxi 2005年01月14日
up
回复 点赞
junglerover 2005年01月14日
再顶一下
回复 点赞
zmhere 2005年01月14日
关注中。。。
回复 点赞
junglerover 2005年01月13日
再顶一下。没有人要分?
回复 点赞
真相重于对错 2005年01月12日
sorry 没看清题.
接分是肯定要接的,争取接到双星,快了还差几百分.
我认为你只是把握不好提交的时机,想找一个通用的只要提交就调用客户端程序的方法.
把问题想复杂了,其实这个控件肯定有一个提交点.一个按钮,或别的,用户点击以后来提交,你只要用
buttton.Attribuate.Add("onclick" , "savedata()");即可
回复 点赞
junglerover 2005年01月12日
hdt(接分接出个星星) 兄你可真逗,果然是接分接出来的星星啊。

帮顶的那一下有分,后面COPY MSDN的一大段没分!典型的不着边际。

我要是连IPostBackDataHandler接口都没有实现,还在这里说个P啊。
回复 点赞
真相重于对错 2005年01月12日
再解答:
你的控件要实现
.NET Framework 类库

IPostBackDataHandler 接口 [C#]请参见
IPostBackDataHandler 成员 | System.Web.UI 命名空间 | 回发数据处理示例 | 处理回发数据 | IPostBackDataHandler 成员(Visual J# 语法) | C++ 托管扩展编程
要求
命名空间: System.Web.UI

平台: Windows 2000, Windows XP Professional, Windows Server 2003 系列

程序集: System.Web (在 System.Web.dll 中)
语言
C#

C++

JScript

Visual Basic

全部显示
定义 ASP.NET 服务器控件为自动加载回发数据而必须实现的方法。

有关此类型所有成员的列表,请参阅 IPostBackDataHandler 成员。

[Visual Basic]
Public Interface IPostBackDataHandler

[C#]
public interface IPostBackDataHandler

[C++]
public __gc __interface IPostBackDataHandler

[JScript]
public interface IPostBackDataHandler

实现 IPostBackDataHandler 的类
类 说明
CheckBox 显示允许用户选择 true 或 false 条件的复选框。
CheckBoxList 创建多项选择复选框组,该复选框组可以通过将控件绑定到数据源动态创建。
DropDownList 表示允许用户从下拉列表中选择一项的控件。
HtmlInputCheckBox 允许编程访问服务器上的 HTML <input type= checkbox> 元素。
HtmlInputFile 允许编程访问服务器上的 HTML <input type= file> 元素。
HtmlInputHidden 允许编程访问服务器上的 HTML <input type=hidden> 元素。
HtmlInputImage 允许编程访问服务器上的 HTML <input type= image> 元素。
HtmlInputRadioButton 允许编程访问服务器上的 HTML <input type= radio> 元素。
HtmlInputText 允许编程访问服务器上的 HTML <input type= text> 和 <input type= password> 元素。
HtmlSelect 允许编程访问服务器上的 HTML <select> 元素。
HtmlTextArea 允许编程访问服务器上的 <textarea> HTML 元素。
ImageButton 显示图像并对图像上的鼠标单击作出响应的控件。
ListBox 表示允许单项或多项选择的列表框控件。
RadioButtonList 表示封装一组单选按钮控件的列表控件。
TextBox 为用户输入显示一个文本框控件。

备注
如果希望设计的服务器控件检查客户端回发到服务器的窗体数据,则必须实现 IPostBackDataHandler 接口。该接口定义的合同允许服务器控件确定其状态是否在回发发生后更改,并引发适当的事件。有关更多信息,请参见处理回发数据。

示例
[Visual Basic, C#] 下面的示例说明实现 IPostBackDataHandler 接口的自定义文本框服务器控件。Text 属性在回发发生后更改,并且服务器控件在回发数据加载后引发文本更改事件。

[Visual Basic]
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Collections
Imports System.Collections.Specialized

Namespace CustomWebFormsControls

<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> Public Class MyTextBox
Inherits Control
Implements IPostBackDataHandler


Public Property Text() As String
Get
Return CType(Me.ViewState("Text"), String)
End Get

Set
Me.ViewState("Text") = value
End Set
End Property


Public Event TextChanged As EventHandler


Public Overridable Shadows Function LoadPostData( _
postDataKey As String, _
postCollection As System.Collections.Specialized.NameValueCollection) _
As Boolean Implements IPostBackDataHandler.LoadPostData

Dim presentValue As String = Text
Dim postedValue As String = postCollection(postDataKey)

If presentValue Is Nothing Or Not presentValue.Equals(postedValue) Then
Text = postedValue
Return True
End If

Return False
End Function


Public Overridable Shadows Sub RaisePostDataChangedEvent() _
Implements IPostBackDataHandler.RaisePostDataChangedEvent

OnTextChanged(EventArgs.Empty)
End Sub


Protected Overridable Sub OnTextChanged(e As EventArgs)
RaiseEvent TextChanged(Me, e)
End Sub


Protected Overrides Sub Render(output As HtmlTextWriter)
output.Write("<INPUT type= text name = " & Me.UniqueID & _
" value = " & Me.Text & " >")
End Sub

End Class

End Namespace

[C#]
using System;
using System.Web;
using System.Web.UI;
using System.Collections;
using System.Collections.Specialized;


namespace CustomWebFormsControls {

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public class MyTextBox: Control, IPostBackDataHandler {


public String Text {
get {
return (String) ViewState["Text"];
}

set {
ViewState["Text"] = value;
}
}


public event EventHandler TextChanged;


public virtual bool LoadPostData(string postDataKey,
NameValueCollection postCollection) {

String presentValue = Text;
String postedValue = postCollection[postDataKey];

if (presentValue == null || !presentValue.Equals(postedValue)) {
Text = postedValue;
return true;
}

return false;
}


public virtual void RaisePostDataChangedEvent() {
OnTextChanged(EventArgs.Empty);
}


protected virtual void OnTextChanged(EventArgs e) {
if (TextChanged != null)
TextChanged(this,e);
}


protected override void Render(HtmlTextWriter output) {
output.Write("<INPUT type= text name = "+this.UniqueID
+ " value = " + this.Text + " >");
}
}
}

[C++, JScript] 没有可用于 C++ 或 JScript 的示例。若要查看 Visual Basic 或 C# 示例,请单击页左上角的“语言筛选器”按钮 。

要求
命名空间: System.Web.UI

平台: Windows 2000, Windows XP Professional, Windows Server 2003 系列

程序集: System.Web (在 System.Web.dll 中)

请参见
IPostBackDataHandler 成员 | System.Web.UI 命名空间 | 回发数据处理示例 | 处理回发数据 | IPostBackDataHandler 成员(Visual J# 语法) | C++ 托管扩展编程


--------------------------------------------------------------------------------

发送有关此主题的意见

© 2001-2002 Microsoft Corporation。保留所有权利。

回复 点赞
真相重于对错 2005年01月12日
先up,骗点分:D
回复 点赞
lib_zhang 2005年01月12日
UP,关注中!
回复 点赞
junglerover 2005年01月12日
请注意:UP有分,但是不明我的意思,说得不着边际的,没分!

大家请参考:
http://community.csdn.net/Expert/topic/3676/3676802.xml?temp=.8058588
回复 点赞
LoveCherry 2005年01月12日
mark
回复 点赞
junglerover 2005年01月12日
再顶一下试试看。
回复 点赞
jedliu 2005年01月12日
我没干过,只好帮你顶上去!
回复 点赞
YIO2002 2005年01月12日
帮你UP
回复 点赞
真相重于对错 2005年01月12日
不知道
回复 点赞
junglerover 2005年01月12日
TO hdt(接分接出个星星) :
很简单啊,只要你在任何aspx网页上放一个Calendar,并点击它的任何日期,该网页都会上传。

WebForm上面的任何服务器端控件(Calendar,Datagrid,等等),都会有自身的操作引起上传。如果这种上传前,不能调用我的SAVEDATA,我的表格中已编辑好的数据就会丢掉!因为它是个非窗体控件。

对于一般的窗体型的Web服务器控件,只要你打开它的EnableViewState属性,在这种上传时,该控件的客户端更改就不会丢失。例如,你把一个Textbox和Calendar放在同一页面上,在TextBox里录入一些内容,再点击Calendar的任意日期,并不会导致Textbox的内容丢失。但是对于非窗体型的控件就不一样了!还没明白我的意思吗?
回复 点赞
发动态
发帖子
C#
创建于2007-09-28

8.4w+

社区成员

64.0w+

社区内容

.NET技术 C#
社区公告
暂无公告