






















Author:水如烟
自联表我们经常用到,它总是跟树联结在一起。
对于它们的处理,.NET没有专门的处理类。
控件类TreeNode,也没有直接跟自联表挂上钩。
所以,我也尝试一下写写这方面的代码。
如我以往所写的一样,仅提供一种方法,至于更好的方法,更好的效率,鉴于自己学识所限,不深究。
通常的,要做成泛型类才能通用。所以,若还是使用.Net FrameWork1.1的话,无法使用下面的类了。
下面是为应用自联表做的树类,只有两个文件:
Node.vb
Namespace LzmTW.uSystem.uCollection<Serializable()> _
Public Class Node(Of T)Friend gIsRoot As Boolean = True
Friend gParent As Node(Of T)''' <summary>
''' 当前节点的父节点
''' </summary>
Public ReadOnly Property Parent() As Node(Of T)
Get
If Me.IsRoot Then
Return Nothing
End If
Return gParent
End Get
End Property''' <summary>
''' 树的深度
''' </summary>
Public ReadOnly Property Level() As Integer
Get
If Me.IsRoot Then
Return 0
End If
Return Me.Parent.Level + 1
End Get
End Property''' <summary>
''' 当前节点是否是根节点
''' </summary>
Public ReadOnly Property IsRoot() As Boolean
Get
Return gIsRoot
End Get
End PropertyPrivate gUserData As Object''' <summary>
''' 获取或设置包含树节点有关数据的对象
''' </summary>
Public Property Tag() As Object
Get
Return gUserData
End Get
Set(ByVal value As Object)
gUserData = value
End Set
End PropertyPrivate gItem As T
Public Property Item() As T
Get
Return gItem
End Get
Set(ByVal value As T)
gItem = value
End Set
End PropertyFriend gChildren As NodeCollection(Of T)''' <summary>
''' 获取第一个子树节点
''' </summary>
Public ReadOnly Property FirstNode() As Node(Of T)
Get
If gChildren.Count = 0 Then
Return Nothing
End If
Return gChildren(0)
End Get
End Property''' <summary>
''' 获取最后一个子树节点
''' </summary>
Public ReadOnly Property LastNode() As Node(Of T)
Get
If gChildren.Count = 0 Then
Return Nothing
End If
Return gChildren(gChildren.Count - 1)
End Get
End PropertyPrivate gNodes As NodeCollection(Of T)''' <summary>
''' 当前节点的节点集合
''' </summary>
Public ReadOnly Property Nodes() As NodeCollection(Of T)
Get
Return gNodes
End Get
End Property''' <summary>
''' 当前节点在节点集合中的位置
''' </summary>
Public ReadOnly Property Index() As Integer
Get
Return GetIndex()
End Get
End PropertyPrivate Function GetIndex() As Integer
If Me.IsRoot Then
Return 0
End IfReturn Me.Parent.Nodes.IndexOf(Me)
End Function''' <summary>
''' 获取下一个同级树节点
''' </summary>
Public ReadOnly Property NextNode() As Node(Of T)
Get
If Me.IsRoot OrElse Me.Index + 1 > Me.Parent.Nodes.Count Then
Return Nothing
End IfReturn Me.Parent.Nodes.Item(Me.Index + 1)
End Get
End Property''' <summary>
''' 获取上一个同级树节点
''' </summary>
Public ReadOnly Property PrevNode() As Node(Of T)
Get
If Me.IsRoot OrElse Me.Index - 1 < 0 Then
Return Nothing
End IfReturn Me.Parent.Nodes.Item(Me.Index - 1)
End Get
End PropertyPrivate Sub Initialzie()
gNodes = New NodeCollection(Of T)(Me)
gChildren = New NodeCollection(Of T)(Me)
End SubSub New()
Initialzie()
End SubSub New(ByVal item As T)
gItem = item
Initialzie()
End SubPublic Function GetNodeCount(ByVal includeSubNodes As Boolean) As IntegergByProperty
= byPropertyMe.ForEach(New Action(Of T)(AddressOf GetDataTableDatasAction), includeSubNodes)gTable.AcceptChanges()
Return gTablegTable.Rows.Add(tmpRow)
End Sub''' <summary>treeNode.Nodes.Add(mCurrentTreeNode)
AppendTreeNode(mCurrentTreeNode, n, byProperty, nameOfTreeNodeText)
NextEnd SubPrivate Shared Function ConvertToTreeNode(ByVal node As Node(Of T), ByVal byProperty As Boolean, ByVal nameOfTreeNodeText As String) As System.Windows.Forms.TreeNodeNodeCollection.vb
Namespace LzmTW.uSystem.uCollection<Serializable()> _
Public Class NodeCollection(Of T)
Inherits System.Collections.ObjectModel.Collection(Of Node(Of T))Private gOwner As Node(Of T)Friend Sub New(ByVal node As Node(Of T))
gOwner = node
End SubPublic Shadows Function Add(ByVal Value As T) As Node(Of T)
Dim mNode As New Node(Of T)(Value)
Add(mNode)
gOwner.gChildren.Add(mNode)
gOwner.gChildren.Remove(mNode)
End SubPublic Shadows Sub Remove(ByVal index As Integer) Insert(index, mNode)
gOwner.gChildren.Insert(index, mNode)
一个辅助的类,专用于序列化用的。
SerializeHelper.vb
Namespace LzmTW.uSystem.uRuntime.uSerializationPublic Class SerializeHelperPrivate Sub New()
End Sub<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function ItemToXml(Of T)(ByVal obj As T) As String
Dim mResult As String = ""
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringWriter As New System.IO.StringWriter
Using mStringWriter
mSerializer.Serialize(mStringWriter, obj)
mResult = mStringWriter.ToString
mStringWriter.Close()
End Using
Return mResult
End Function<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlToItem(Of T)(ByVal xml As String) As T
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringReader As New System.IO.StringReader(xml)
Return CType(mSerializer.Deserialize(mStringReader), T)
End Function<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToXmlFile(Of T)(ByVal filename As String, ByVal obj As T)
Dim XmlWriter As New System.IO.StreamWriter(filename, False, System.Text.Encoding.Default)
Using XmlWriter
XmlWriter.Write(ItemToXml(obj))
XmlWriter.Close()
End Using
End Sub<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlFileToItem(Of T)(ByVal filename As String) As T
Dim XmlReader As New System.IO.StreamReader(filename, System.Text.Encoding.Default)
Dim mObj As T
Using XmlReader
mObj = XmlToItem(Of T)(XmlReader.ReadToEnd)
XmlReader.Close()
End Using
Return mObj
End Function<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToFormatterFile(Of T)(ByVal filename As String, ByVal formatter As System.Runtime.Serialization.IFormatter, ByVal obj As T)
Dim mFileStream As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)
Using mFileStream
formatter.Serialize(mFileStream, obj)
mFileStream.Close()
End Using
End Sub<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function FormatterFileToItem(Of T)(ByVal FileName As String, ByVal formatter As System.Runtime.Serialization.IFormatter) As T
Dim mFileStream As System.IO.Stream = System.IO.File.Open(FileName, System.IO.FileMode.Open)
Dim mObj As T
Using mFileStream
mObj = CType(formatter.Deserialize(mFileStream), T)
mFileStream.Close()
End Using
Return mObj
End FunctionPublic Shared Function Clone(Of T)(ByVal obj As T) As T
Dim tmpT As T
Dim mFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mMemoryStream As New System.IO.MemoryStream
Using mMemoryStream
mFormatter.Serialize(mMemoryStream, obj)
mMemoryStream.Position = 0
tmpT = CType(mFormatter.Deserialize(mMemoryStream), T)
mMemoryStream.Close()
End Using
Return tmpT
End FunctionPublic Shared Sub Save(Of T)(ByVal filename As String, ByVal formattype As FormatType, ByVal obj As T)
Select Case formattype
Case formattype.Binary
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, obj)
Case formattype.Soap
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter, obj)
Case formattype.Xml
ItemToXmlFile(filename, obj)
End Select
End SubPublic Shared Function Load(Of T)(ByVal filename As String, ByVal formattype As FormatType) As T
Select Case formattype
Case formattype.Binary
Return FormatterFileToItem(Of T)(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)
Case formattype.Soap
Return FormatterFileToItem(Of T)(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter)
Case formattype.Xml
Return XmlFileToItem(Of T)(filename)
End Select
Return Nothing
End FunctionEnd ClassPublic Enum FormatType
Xml
Binary
Soap
End EnumEnd Namespace
现在可以测试一下。
测试代码:
Public Class Form1Private gNode As New uSystem.uCollection.SinceLink.Node(Of item)(New item("Root"))Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
gNode.Nodes.add(
New item("First"))效果:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。