DataSourceControl基类
它用来作为控件的基类,其派生类通常用来作为数据绑定控件的数据源。
所在命名空间:System.Web.UI
所在程序集:System.Web(System.Web.dll中)
ASP.NET支持控件数据绑定结构,该结构使Web服务器控件 能够 以一致的方式 绑定到数据。
绑定到数据的web服务器控件称为数据绑定控件,促成这种绑定的类 称为 数据源控件。
数据源控件可以表示任何数据源(关系数据库、文件、流、业务对象等)。数据源控件 以一致的方式 向数据绑定控件提供数据,而不管 基础数据的源和格式 如何。
如果要实现自己的自定义数据源控件,则应使用DataSourceControl做基类继承。
实现IDataSource接口的所有类都是数据源控件,但大多数ASP.NET数据源控件都扩展DataSourceControl抽象类,该类实现了IDataSource接口的基实现。
DataSourceControl类 还提供了 IListSource接口的实现(可以提供 以编程方式将数据源控件分配给数据绑定控件的DataSource属性,并将数据作为基本列表返回给该控件)
(从DataBoundControl类派生的 所有ASP.NET控件)都可以绑定到数据源控件。
当绑定到数据源控件时,会在运行时自动执行数据绑定。
【数据绑定】要符合以下条件:
- 公开DataSource属性或DataSourceID属性
- 支持基本数据绑定
- 可以不从DataBoundControl类派生
在使用数据绑定控件时,必须显示调用DataBind方法。
可以将【数据源控件】视为:DataSourceControl对象 及其 关联数据列表(称为数据源视图)的组合。
数据列表有一个DataSourceView对象表示。
DataSourceControl总是与 一个或多个 指定DataSourceView对象关联。
IDataSource接口定义了 所有数据源控件 用于跟数据源视图交互的方法。
- GetViewNames——用于 枚举 当前与数据源控件关联的数据源视图
- GetView——用于 按名称 检索特定的数据源视图实例
DataSourceControl类是 页开发者 在开发web窗体时 直接进行交互的接口
DataSourceView类是 数据绑定控件开发时 交互的接口。DataSourceView对象只在运行时可用,因此(为数据源控件 或 数据源视图保留的)任何状态 都必须 由数据源控件直接公开。
ASP.NET数据源控件没有可视化呈现,因此,不支持可视化功能。
示例
演示如何扩展DataSourceControl类。
Imports System
Imports System.Collections
Imports System.Data
Imports System.IO
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.VisualBasic
Namespace Samples.AspNet.VB.Controls
<AspNetHostingPermission(SecurityAction.Demand, level:=AspNetHostingPermissionLevel.Minimal)> _
Public Class CsvDataSource
Inherits DataSourceControl
Public Sub New() '控件一般都必须提供 无参数构造函数
End Sub
'关联 CSV文件名
Public Property FileName() As String
Get
Return CType(Me.GetView([String].Empty), CsvDataSourceView).SourceFile
End Get
Set(ByVal value As String)
If CType(Me.GetView([String].Empty), CsvDataSourceView).SourceFile <> value Then
CType(Me.GetView([String].Empty), CsvDataSourceView).SourceFile = value
RaiseDataSourceChangedEvent(EventArgs.Empty)
End If
End Set
End Property
'设置 是否包含列名
Public Property IncludesColumnNames() As Boolean
Get
Return CType(Me.GetView([String].Empty), CsvDataSourceView).IncludesColumnNames
End Get
Set(ByVal value As Boolean)
If CType(Me.GetView([String].Empty), CsvDataSourceView).IncludesColumnNames <> value Then
CType(Me.GetView([String].Empty), CsvDataSourceView).IncludesColumnNames = value
RaiseDataSourceChangedEvent(EventArgs.Empty)
End If
End Set
End Property
'首先“扩展DataSourceControl”必须 实现其
'GetView和GetViewNames
Private view As CsvDataSourceView = Nothing '准备一个强类型的视图对象,用来返回给当前数据源控件
Protected Overrides Function GetView(ByVal viewName As String) As System.Web.UI.DataSourceView
If view Is Nothing Then '扩展DataSourceControl,必须同时派生DataSourceView
view = New CsvDataSourceView(Me, String.Empty)
End If
Return view
End Function
Protected Overrides Function GetViewNames() As System.Collections.ICollection
Dim al As New ArrayList(1)
al.Add(CsvDataSourceView.DefaultViewName)
Return CType(al, ICollection)
End Function
End Class
Public Class CsvDataSourceView
Inherits DataSourceView
'DataSourceView的派生类 需要指定Owner和名字
Public Sub New(ByVal owner As IDataSource, ByVal name As String)
MyBase.New(owner, name)
End Sub
'提供 默认名字
Public Shared DefaultViewName As String = "CommaSeparatedView"
'指示CSV文件 位置和名称
Private aSourceFile As String = [String].Empty
Friend Property SourceFile() As String
Get
Return aSourceFile
End Get
Set(ByVal value As String)
Dim mappedFileName As String = HttpContext.Current.Server.MapPath(value)
aSourceFile = mappedFileName
End Set
End Property
'是否包含 列名行
Private columns As Boolean = False
Public Property IncludesColumnNames() As Boolean
Get
Return columns
End Get
Set(ByVal value As Boolean)
columns = value
End Set
End Property
'因为主要使用 查询功能,这里就是代码最多的地方
Protected Overrides Function ExecuteSelect(ByVal selectArgs As System.Web.UI.DataSourceSelectArguments) As System.Collections.IEnumerable
'返回值是一个序列,下面是准备的返回序列
Dim dataList As IEnumerable = Nothing
If File.Exists(Me.SourceFile) Then
'思路就是将CSV文件按行拆分,填入DataTable中
Dim data As New DataTable
Dim sr As StreamReader = File.OpenText(Me.SourceFile)
Try
'准备分析 列名行
Dim dataValues() As String
Dim col As DataColumn
dataValues = sr.ReadLine.Split(","c)
Dim token As String
For Each token In dataValues
col = New DataColumn(token, System.Type.GetType("System.String"))
data.Columns.Add(col)
Next
If Not IncludesColumnNames Then
data.Rows.Add(CopyRowData(dataValues, data.NewRow))
End If
'分析并填入数据行
Dim s As String
Do
s = sr.ReadLine
If Not s Is Nothing Then
dataValues = s.Split(","c)
data.Rows.Add(CopyRowData(dataValues, data.NewRow))
End If
Loop Until s Is Nothing
Finally
sr.Close()
End Try
data.AcceptChanges()
Dim dataview As New DataView(data)
If Not selectArgs.SortExpression Is String.Empty Then
dataview.Sort = selectArgs.SortExpression
End If
dataList = dataview '数据视图可以直接赋值给序列
Else
Throw New System.Configuration.ConfigurationErrorsException("File not found, " & Me.SourceFile)
End If
If dataList Is Nothing Then
Throw New InvalidOperationException("no data loaded from data source.")
End If
Return dataList
End Function
'用来复制数据行
Private Function CopyRowData(ByVal [source]() As String, ByVal target As DataRow) As DataRow
Try
Dim i As Integer
For i = 0 To [source].Length - 1
target(i) = [source](i)
Next
Catch iore As IndexOutOfRangeException
Return target
End Try
Return target
End Function
'下面一系列 覆盖 用来关闭 增删改功能
Public Overrides ReadOnly Property CanDelete() As Boolean
Get
Return False
End Get
End Property
Protected Overrides Function ExecuteDelete(ByVal keys As System.Collections.IDictionary, ByVal oldValues As System.Collections.IDictionary) As Integer
Throw New NotSupportedException
End Function
Public Overrides ReadOnly Property CanInsert() As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property CanUpdate() As Boolean
Get
Return False
End Get
End Property
Protected Overrides Function ExecuteInsert(ByVal values As System.Collections.IDictionary) As Integer
Throw New NotSupportedException
End Function
Protected Overrides Function ExecuteUpdate(ByVal keys As System.Collections.IDictionary, ByVal values As System.Collections.IDictionary, ByVal oldValues As System.Collections.IDictionary) As Integer
Throw New NotSupportedException
End Function
End Class
End Namespace
使用 CsvDataSource控件
<%@ Page Language="VB" %>
<%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.VB.Controls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID=gv1 DataSourceID=cds1 runat=server AllowSorting=true />
</div>
<aspsample:csvDataSource id="cds1" runat="server" filename="~\samples.csv" includescolumnnames="true" />
</form>
</body>
</html>
总结
扩展DataSourceControl类 至少需要 自定义2个类:
- DataSourceControl的派生类
其中 必须实现 GetView方法 和 GetViewNames方法;还可以添加一些辅助方法,如文件位置、是否含列名行等。
- DataSourceView的派生类
首先,必须有2个参数的构造函数,用来指明Owner和Name;
必须自己管理其ViewName,以便必要时返回给DataSourceControl派生类;
最重要的是,必须处理一系列增删改方法,包括:ExecuteSelect、ExecuteInsert、ExecuteDelete、ExecuteUpdate;CanInsert、CanDelete、CanUpdate。
使用 自定义数据源控件 的步骤:
- 首先,必须注册控件 <%@ Register TagPrefix=”” Namespace=”” %>
- 其次,用正确的标记前缀引用,设置其必要属性