65.9K
CodeProject 正在变化。 阅读更多。
Home

支持拖放并持久化的 TreeView 控件 (VB.NET)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.55/5 (21投票s)

2005年1月27日

CPOL

4分钟阅读

viewsIcon

152955

downloadIcon

2967

扩展 TreeView 控件以支持拖放和持久化。

引言

在之前的文章 TreeView 拖放入门使用序列化持久化 TreeView 控件 中,我们探讨了如何对 TreeView 控件实例进行持久化和实现拖放功能。在本文中,我们将更进一步,通过扩展 TreeView 控件来整合这些功能,使其能够在您的项目中重复使用。

本文不涵盖前几篇文章中介绍的主题,仅重点介绍将这些功能实现到扩展的 TreeView 类所需的更改。因此,如果您想完全理解该项目,建议您先熟悉这些文章。

入门

首先,我们创建一个继承自标准 TreeView 控件的自定义用户控件。

Public Class DragDropPersistingTreeView
    Inherits System.Windows.Forms.TreeView
    
    ...

End Class

通常,在创建自定义用户控件时,我们会包含 Inherits System.Windows.Forms.UserControl,这为我们提供了一个空白控件来使用。在这里,我们将此行替换为 Inherits System.Windows.Forma.TreeView,这允许我们的新控件自动包含 TreeView 控件的所有功能,而无需额外的编码。

重写拖放方法

在文章 TreeView 拖放入门 中,我们必须在父窗体内部处理与拖放活动相关的 TreeView 控件触发的事件。

Public Sub TreeView1_ItemDrag(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.ItemDragEventArgs) _
    Handles TreeView1.ItemDrag
        
    'Set the drag node and initiate the DragDrop 
    DoDragDrop(e.Item, DragDropEffects.Move)

End Sub

现在我们正在扩展 TreeView 控件,我们需要在类中处理拖放事件,因此上述方法需要替换为

Protected Overrides Sub OnItemDrag( _
    ByVal e As System.Windows.Forms.ItemDragEventArgs)
    
    'Ensure the base method is called 
    MyBase.OnItemDrag(e)
    
    'Set the drag node and initiate the DragDrop 
    DoDragDrop(e.Item, DragDropEffects.Move)

End Sub

在重写继承类中的方法时,确保用相关参数调用基类中的重写方法非常重要。这是为了确保任何在类外部监听该事件的委托仍然能接收到该事件,因此我们包含以下行:

MyBase.OnItemDrag(e)

请注意,此方法声明为 Protected,这意味着它仅对从此类派生的类可用。因此,您将无法从放置控件的窗体或控件访问 TreeView 的 OnItemDrag 方法。

OnDragEnterOnDragOverOnDragDropOnDragLeave 方法也以这种方式被重写;完整的文档包含在页面顶部的附加项目源代码中。通过重写这些方法,您已经扩展了标准的 TreeView 控件以支持基本的拖放操作。

有关重写方法的更多信息,MSDN 是一个很好的起点。

持久化 TreeView 数据

在文章 使用序列化持久化 TreeView 控件 中,我们创建了两个可序列化的结构来表示 TreeView 及其 TreeNode 集合。这些结构直接摘自该文章并放置在扩展的 TreeView 类中。然而,用于公开加载和保存功能的方法需要稍作修改。

Public Sub SaveToXml(ByVal path As String)
        
    'Create as serializer and file to save TreeViewData
    Dim ser As New _
        System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
    Dim file As New System.IO.FileStream(path, IO.FileMode.Create)
    Dim writer As New System.Xml.XmlTextWriter(file, Nothing)
    
    'Generate TreeViewData from TreeView and serialize the file
    ser.Serialize(writer, New TreeViewData(Me))
    
    'Tidy up
    writer.Close()
    file.Close()
    file = Nothing

End Sub
    
    
Public Sub LoadFromXml(ByVal path As String)
    
    'Create as serializer and get the file to deserialize
    Dim ser As New _
        System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
    Dim file As New System.IO.FileStream(path, IO.FileMode.Open)
    Dim reader As New System.Xml.XmlTextReader(file)

    'Deserialize the file and populate the treeview
    Dim treeData As TreeViewData = _
        CType(ser.Deserialize(reader), TreeViewData)
    treeData.PopulateTree(Me)

    'Tidy up
    reader.Close()
    file.Close()
    file = Nothing
        
End Sub

同样,我们使用 XmlSerializer 来完成存储和检索 TreeView 数据的繁重工作。然而,与(在 原始文章 中)将作为参数传递的 TreeView 对象的数据持久化不同,这里我们将扩展的 TreeView 本身持久化,将其作为参数传递给 TreeViewData 构造函数和 PopulateTree 方法。

使用控件

页面顶部的下载提供了示例项目,其中包含正在运行的 DragDropPersistingTreeView 控件,以及一个单独的控件类文件。您可以将此类构建到您自己的项目中,或像使用任何其他用户控件一样使用它,将其从工具箱拖到您的窗体或控件设计器上。

只要您将 AllowDrop 属性设置为 True,拖放功能就能立即使用。要加载和保存 TreeView 的内容,请在您的窗体中添加几个按钮并处理它们的 Click 事件。

Private Sub SaveButton_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles SaveButton.Click

    DragDropPersistingTreeView1.SaveToXml( _
        "C:\Temp\DragDropPersistingTreeView1.xml")

End Sub

Private Sub LoadButton_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles LoadButton.Click

    DragDropPersistingTreeView1.LoadFromXml( _
        "C:\Temp\DragDropPersistingTreeView1.xml")

End Sub

结论

我希望本文能为扩展控件,特别是 TreeView,提供一个有趣的入门介绍,将先前文章中开发的功能整合到一个控件中。

相关文章

如果您觉得这篇文章很有趣,您可能还会对其他与 TreeView 控件相关的入门文章感兴趣:

© . All rights reserved.