自动更新作为简单自定义控件





3.00/5 (3投票s)
2006年11月2日
6分钟阅读

44385

470
本文介绍了一种使用自定义控件实现页面自动刷新功能的简便方法。
引言
本文介绍了一种使用自定义控件实现页面自动刷新功能的简便方法。虽然在每个需要自动刷新的页面上键入文本来实现此功能足够简单,但创建自定义控件来处理任意数量页面的任务也同样简单。通过放置自定义控件,开发人员只需将控件拖放到窗体上,并在 IDE 的属性编辑器中设置更新间隔属性,即可添加自动刷新功能。
执行页面的自动刷新通常是一种可疑的做法,但在某些情况下,这是必要的。例如,如果您正在开发一个基于 Web 的 GIS 解决方案,用于跟踪 GPS 启用的长途卡车,您可能希望使用浏览器窗口来研究一名卡车司机的冒险经历。为了继续获取卡车位置的更新,如果页面定期自动刷新以更新卡车位置,用户可能会负担较小(而不是要求用户连续按下浏览器的刷新按钮)。除了这个例子,该控件在页面旨在显示任何连续更新的值(如股票价格)或监视某些内容(如在线拍卖的最后竞价时刻)时也可能有用。
使用该控件时,应将更新间隔设置为合理的值。例如,您通常不希望控件每秒更新一次页面,但您可能希望每分钟捕获一次更新。此外,如果页面包含其他控件,则必须严格维护这些控件的状态,以防止用户在用户手动回发之间丢失输入。
鉴于近期对 AJAX 的关注,基于计时器的局部页面更新可能是一种更合理的方法来满足大多数需求。但是,在某些情况下,执行周期性的整个页面更新仍然不是坏事,该控件就是为这类情况设计的。
入门
要开始,请解压缩下载的文件并打开提供的项目。在解决方案中,您会找到两个项目,一个是名为“AutoUpdate”的控件库,另一个是测试网站。
图 1:解决方案资源管理器
控件库仅包含一个名为“AutoRefresh.vb”的类。这个简单的类定义了自定义控件及其属性和方法。
测试网站包含一个网页(default.aspx)。该页面包含 Auto Refresh 控件的一个实例,并且为了演示,包含一个 Label
控件,该控件在每次触发页面加载事件时都会使用当前时间进行更新。
网站的 bin 文件夹包含对 Auto-Update 动态链接库 (DLL) 的引用。
图 2:运行中的测试网站
代码:AutoRefresh.vb
自动刷新控件类非常简单;该类仅包含默认的库导入,并且类本身继承自 WebControl
类。代码的第一部分如下:
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
<DefaultProperty("Update Interval"), _
ToolboxData("<{0}:AutoRefresh " & _
"runat=server></{0}:AutoRefresh>")>_
Public Class AutoRefresh
Inherits WebControl…
该类中的下一部分代码同样简单。在类声明之后,声明了一个用于存储更新时间间隔值的私有成员变量。在该变量声明之后,下一段代码处理控件的初始化事件,在该事件处理程序中,控件被赋予 20 x 20 像素的默认大小。这除了使控件在设计时可见,以便使用该控件的开发人员可以选择它并将其属性加载到属性网格中之外,没有其他有用的目的。如果您愿意,可以为控件着色并输入一些文本(例如控件名称),但我没有在设计时对控件的外观做任何特殊处理。
Private mTimeInterval As Integer
Private Sub AutoRefresh_Init(ByVal sender As Object, _
ByVal e As System.EventArgs)
Handles Me.Init
Me.Height = 20
Me.Width = 20
End Sub
在初始化事件处理程序之后,声明了一个属性,该属性用于设置或获取通过本地时间间隔成员变量 (mTimeInterval
) 允许的更新之间的当前时间间隔。
<Category("Update Interval")>_
<Browsable(True)>_
<Description("Set the interval at which the" & _
" page will refresh (in seconds)")>_
Property TimeInterval() As Integer
Get
Return mTimeInterval
End Get
Set(ByVal value As Integer)
mTimeInterval = value
End Set
End Property
在检查属性代码时,请注意 Category
、Browsable
和 Description
属性已包含在属性声明中。这些属性在 Visual Studio IDE 中为控件提供设计时支持。当在 IDE 的属性编辑器中显示时间间隔变量时,这些填充的属性会设置属性网格的文本和描述。
最后要做的就是渲染控件。在这种情况下,控件实际上没有任何可视化效果,所以它只是被添加到页面中。这是通过重写默认的 RenderContents
子例程来实现的。
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
Try
Dim sb As New StringBuilder
sb.Append("<meta http-equiv='Refresh' content=" & TimeInterval & "> ")
writer.RenderBeginTag(HtmlTextWriterTag.Div)
writer.Write(sb.ToString())
writer.RenderEndTag()
Catch ex As Exception
' if there is an error, the control will just display 'Auto Refresh'
writer.RenderBeginTag(HtmlTextWriterTag.Div)
writer.Write("Auto Refresh")
writer.RenderEndTag()
End Try
End Sub
End Class
在检查此代码时,请注意渲染选项包含在 Try Catch
块中,目的是捕获渲染控件时发生的任何错误,并允许控件在操作因任何原因失败时渲染一些安全的内容。如果此潜在错误未被捕获且发生错误,IDE 将以不友好的方式显示错误。
还要注意,HTMLTextWriter
将刷新标签放入页面上的一个 div
中。可以将其写入 head
,但 Microsoft 没有提供方便的方法来实现这一点,并且用于此目的的解决方法通常不值得努力(在本例中也是如此)。好消息是,即使将控件放入 div
中,它也能正常工作。您还可以重写 HTMLTextWriter
的开始标签(例如,您可以将其更改为使用 head
标签而不是 div
),它也能工作,但它仍然会将标签放在控件的插入点,而不是实际的 head
中。
代码:Default.aspx
测试网站只有一个网页,即 default.aspx。该页面很简单,除了显示当前时间之外,什么都不做;当前时间在初始页面加载时显示,并在每次回发后更新。时间本身显示在 ASP.NET Label
控件中。除了 Label
之外,该页面还添加了一个自动更新控件的副本,并且通过设计时属性编辑器支持将其间隔设置为 10 秒。
图 3:Auto-Refresh 控件的设计时支持
项目中唯一真正的代码是页面加载事件处理程序。
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
lblTime.Text = DateTime.Now.ToShortTimeString()
End Sub
End Class
如您所见,这里发生的事情是,每次页面加载时,ASP.NET Label
控件都会更新以显示当前时间。自动刷新控件将强制页面在“TimeInterval
”属性中指定的间隔进行更新,并且作为对每次更新的响应,页面加载事件将触发,时间也将更新。
这几乎涵盖了构建自定义控件和在 Web 应用程序上下文中使用它的所有编码工作。
摘要
虽然演示控件和项目代表了构建自定义控件的一个非常简单的示例,但它作为一个控件(如果谨慎使用)以及作为构建 ASP.NET 自定义控件所用过程的示例,仍然具有一定的价值。人们可以应用此演示中使用过的相同基本过程来构建任意数量的独特自定义控件。