熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

VB.NET中層次數據綁定TreeView的實現

2013-11-13 10:31:50  來源: .NET編程 
      提要:在VB常將TreeView用來表示層次數據但相關的與數據庫進行交互的代碼需要大量的采用手工編碼;在中由於數據綁定功能的加強及語言特性的增強可以很容易的實現TreeView與層次數據的綁定本文將首先建立一個繼承自TreeView的 dbTreeView然後用一個單位(部門)的層次數據與dbTreeView進行數據綁定並提供了與數據庫進行交互的代碼

  從層次數據的表達方式開始

  在本例中部門表(department)中有五個字段如下表:

字段名 字段 類型說明 ID 自動編號 Key Code String 編碼 Name String 名稱 PID Int 父結點的ID CPtr boolean 是否有子結點  
  繼承自TreeNode的myTreeNode

  在myTreeNode中新增了三個屬性如下表:

屬性名 類型 說明 Value Object Key PID Object 父結點的ID CPtr Boolean 是否有子結點  
  在Init事件中根據傳入的四個參數設置這三個屬性和Text屬性

  將dbTreeView綁定到數據源

屬性名 類型 說明 Datasource dataview dbTreeVIew的數據源使用dataview而不是object Value Member string值成員(數據源[dataview]的列名) Display Member string顯示(在Text中)成員 Pid Member string父ID成員 CPtr Member string是否有子結點  
  後四個屬性對應myTreeNode的valuetextpidcptr

  相關代碼如下:

Protected Property DataSource() As Object
 Get
  Return mDataView
 End Get

 Set(ByVal Value As Object)
  If Value Is Nothing Then
  Else
   mDataView = Value
   cm = CType(MeBindingContext(mDataView) CurrencyManager)
   UpdateTreeView()
  End If
 End Set
End Property

Protected Property PidMember() As String
 Get
  Return mPidMember
 End Get
 Set(ByVal Value As String)
  mPidMember = Value
 End Set
End Property

Protected Property DisplayMember() As String
 Get
  Return Join(mDisplayMember SplitChar)
 End Get
 Set(ByVal Value As String)
  mDisplayMember = Split(Value SplitChar)
 End Set
End Property

注意這幾個屬性都是保護成員必須在Init事件中設置:

Public Sub Init(ByVal dispmember As String ByVal valuemember As String ByVal pidmember As String ByVal cptrmember As String ByVal datasource As DataView)
 MeValueMember = valuemember
 MeDisplayMember = dispmember
 MePidMember = pidmember
 MeCPtrMember = cptrmember
 MeDataSource = datasource
 取value最大值新增時將value+保證關健值唯一
 MemDataViewSort = MeValueMember
 Mem_MaxID = MeGetValue(MemDataViewCount )
End Sub

  設置DisplayMember屬性的格式如:字段;字段;字段

  在設置屬性時將傳來的參數轉換為字符串數組mDisplayMember在檢索值時返回數據如:值

Protected Overridable Function GetDisplay(ByVal Index As Integer) As Object
 Dim i As Integer
 Dim temp As String =
 For i = To mDisplayMemberLength
  temp = temp & IIf(i > LinkChar ) & mDataView(Index)(mDisplayMember(i))
 Next
 Return temp
End Function
  其它檢索值的函數請參見源程序
生成樹

  UpdateTreeView調用私有方法FillTree來生成樹需要注意的FillTree只是生成指定結點的子結點並將其添加到指定結點而不是一次就將所有結點添加到樹中如果未指定結點(第一次填充時)只是添加頂層結點

Private Sub FillTree(ByRef pnode As myTreeNode Optional ByVal filter As String = )
 mDataViewRowFilter = filter
 Dim i As Integer icol As Integer
 Dim newnode As myTreeNode
 RemoveHandler cmPositionChanged AddressOf cm_PositionChanged
 MeBeginUpdate()
 For i = To mDataViewCount()
  newnode = New myTreeNode(GetDisplay(i) GetValue(i) GetPid(i) GetCPtr(i))
  當有子結點時為這個結點添加一個空子結點
  If newnodeCPtr Then
   Dim nullnode As New myTreeNode()
   nullnodeValue = NoExpandNodeValue
   newnodeNodesAdd(nullnode)
  End If
  If pnode Is Nothing Then
   MeNodesClear()
   MeNodesAdd(newnode)
  Else
   pnodeNodesAdd(newnode)
  End If
 Next
 MeEndUpdate()
 mDataViewRowFilter =
 AddHandler cmPositionChanged AddressOf cm_PositionChanged
End Sub
  在展開有子結點的結點前刪除所有子結點再用FillTree為待展開結點新增子結點

Private Sub dbTreeView_BeforeExpand(ByVal sender As Object ByVal e As SystemWindowsFormsTreeViewCancelEventArgs) Handles MyBaseBeforeExpand
 當是新增結點引起BeforeExpand事件時直接退出
 If ExpandWhenAddNode Then Exit Sub
 在展開結點前更新子結點
 Dim currentnode As myTreeNode = CType(eNode myTreeNode)
 With currentnode
  NodesClear()
  FillTree(currentnode mPidMember & = & CInt(Value))
 End With
End Sub
  實現數據與綁定控件的同步

  要實現兩個方面的同步:

   其它綁定控件(如textbox等)應與TreeView當前結點所指向的記錄位置一致

Private Sub dbTreeView_AfterSelect(ByVal sender As Object ByVal e As SystemWindowsFormsTreeViewEventArgs) Handles MyBaseAfterSelect

 If eNode Is Nothing Then Exit Sub
 定位到position
 cmPosition = GetPosition(CType(eNode myTreeNode)Value)
 If AllowEdit Then
  oldNode = eNode
  oldPos = cmPosition
 End If
End Sub
  在其它綁定控件改變了數據源後更新樹結點這個工作在觸發CurrencyManager的PositionChanged事件時進行

Public Sub cm_PositionChanged(ByVal sender As Object ByVal e As SystemEventArgs)
 If CType(MeSelectedNode myTreeNode)Value <> GetValue(cmPosition) Then
  DebugWriteLine(Current node isnt correct point to currencymanagerposition!)
  MeSelectedNode = FindNodeByValue(GetValue(cmPosition) MeNodes)
 End If
 If AllowEdit Then
  If MeSelectedNode Is Nothing AndAlso cmPosition = cmCount Then
   當新增記錄時新增樹結點
   If CType(cmCurrent DataRowView)IsNew Then
    MeSelectedNode = AddNode(cmPosition)
    Exit Sub
   End If
  End If
  If Not oldNode Is Nothing Then
   If CType(oldNode myTreeNode)Value = GetValue(oldPos) Then
    更新老結點
    oldNodeText = GetDisplay(oldPos)
   Else
   End If
  End If
 End If
End Sub

  使用dbTreeView

  程序運行後界面如下:

  

  相關代碼請參見源程序這裡不做詳述

  需要注意的是刪除操作並沒有刪除子結點只是刪除當前結點而已刪除子結點的工作應該在存儲過程中遞歸實現而不應放在前端


From:http://tw.wingwit.com/Article/program/net/201311/13916.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.