开始写xpnsoft的Web代码了,自己对web编程实在不熟悉,涉及到层次数据TreeVIew实现时,参照winform的方法去实现(http://blog.csdn.net/zwq78/archive/2008/05/18/2455889.aspx),但在web中,用继承方法自定义控件并不是件容易的事,只好另写了一个类,用代理的方法将层次数据绑定treeview的代码封装在该类中,程序如下:
Imports System.ComponentModel
Public Class tvCodeItem
Private mValueMember As String
Private mDisplayMember() As String
Private mHasChild As Boolean
Private mPidMember As String
Private mCPtrMember As String
Private mDataTable As DataTable
Private mtv As TreeView
Public Property PidMember() As String
Get
Return mPidMember
End Get
Set(ByVal Value As String)
mPidMember = Value
End Set
End Property
Public Property CPtrMember() As String
Get
Return mCPtrMember
End Get
Set(ByVal Value As String)
mCPtrMember = Value
End Set
End Property
Public Property ValueMember() As String
Get
Return mValueMember
End Get
Set(ByVal Value As String)
mValueMember = Value
End Set
End Property
Public Property DisplayMember() As String
Get
Return Join(mDisplayMember, SPLITSTRING)
End Get
Set(ByVal Value As String)
mDisplayMember = Split(Value, SPLITSTRING)
End Set
End Property
Public Property DataSource() As DataTable
Get
Return mDataTable
End Get
Set(ByVal Value As DataTable)
mDataTable = Value
End Set
End Property
Function GetValue(ByVal r As DataRow) As Object
Return r(mValueMember)
End Function
Function GetDisplay(ByVal r As DataRow) As Object
Dim i As Int32
Dim temp As String = ""
For i = 0 To mDisplayMember.Length - 1
temp = temp & IIf(i > 0, LINKSTRING, "") & r(mDisplayMember(i))
Next
Return temp
End Function
Function GetPid(ByVal r As DataRow) As Object
Return r(mPidMember)
End Function
Function GetCPtr(ByVal r As DataRow) As Boolean
Return r(mCPtrMember)
End Function
Public Shadows Sub Init(ByVal collid As Int32, Optional ByVal dispmember As String = "") ', _
If dispmember = "" Then
dispmember = DefaultShowFields
End If
If collid = 0 Then Exit Sub
If Me.CollectID = collid Then
Exit Sub
End If
Dim dt As DataTable, dtsource As DataTable
Dim filter As String = "collectid=" + collid.ToString
cbase.GetCodeItemDataRows(collid) '并不是进入系统就加载了所有CodeItem,所以需要在每次使用前调用GetCodeItemDataRows
dtsource = cbase.GetDataTable("codeitem")
dt = dtsource.Clone
Dim dr() As DataRow
dr = dtsource.Select(filter)
Dim i As Int32
For i = 0 To dr.Length - 1
dt.ImportRow(dr(i))
Next
With Me
.PidMember = "pid"
.CPtrMember = "cptr"
.DisplayMember = dispmember
.ValueMember = "id"
'要在所有字段成员赋值完成后,再给datasource写入值。
.DataSource = dt
End With
Me.FillTreeNode(Nothing, "pid=0")
Me.CollectID = collid
End Sub
Private Sub FillTreeNode(ByRef pnode As TreeNode, ByVal filter As String)
If pnode Is Nothing Then mtv.Nodes.Clear()
Dim rows As DataRow() = Me.DataSource.Select(filter)
Dim r As DataRow
Dim newnode As myTreeNode
For Each r In rows
newnode = New myTreeNode(GetDisplay(r), GetValue(r), GetPid(r), GetCPtr(r))
newnode.PopulateOnDemand = newnode.CPtr
If pnode Is Nothing Then
mtv.Nodes.Add(newnode)
Else
pnode.ChildNodes.Add(newnode)
End If
Next
End Sub
Private mCollectID As Int32
Public Property CollectID() As Int32
Get
Return mCollectID
End Get
Set(ByVal Value As Int32)
mCollectID = Value
End Set
End Property
Public Sub New(ByVal tv As WebControls.TreeView)
Me.mtv = tv
End Sub
Public Sub TreeNodePopulate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs)
If e.Node.PopulateOnDemand Then
FillTreeNode(e.Node, "pid=" + e.Node.Value.ToString)
End If
End Sub
End Class
客户端调用:
Dim x As New tvCodeItem(Me.tvFilter)
x.Init(collectid)
Me.Session("tvcodeitem") = x
Protected Sub tvFilter_TreeNodePopulate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) Handles tvFilter.TreeNodePopulate
Dim x As tvCodeItem = CType(Me.Session("tvcodeitem"), tvCodeItem)
x.TreeNodePopulate(sender, e)
End Sub
说明:
1、codeitem相当于所有的代码集合(数据字典),进入系统时并不是全部加载,是在需要的时候,从数据库加载(collectID=?)
2、将tv.TreeNodePopulate写在tvcodeitem中不会被触发,只有在客户端调用。