自定義瀏覽器(文件資源管理器助手組件)
DevExpress WinForms套件附帶了默認的WinForms文件/文件夾對話框的可皮膚對應:XtraFolderBrowserDialog、XtraOpenFileDialog和XtraSaveFileDialog。FileExplorerAssistant組件允許您在表單或UserControl中嵌入類似的功能,并構建可以導航本地存儲或虛擬節點層次結構的自定義文件/文件夾瀏覽器。
瀏覽器默認文件夾
本節解釋FileExplorerAssistant的核心概念,并演示如何構建類似于Windows資源管理器的標準文件/文件夾瀏覽器。

將FileExplorerAssistant組件放在表單或UserControl上,并調用其智能標記菜單。

點擊“Add…”動作來添加所有三個瀏覽器組件:
- 側邊導航菜單(TreeList控件)。
- 主客戶端區域(GridControl控件)。
- 地址欄(BreadCrumbEdit控件)。
所有部件都是默認的DevExpress控件,附帶了FileExplorerAssistant extensions,擴展自定義控件的外觀和行為,并允許這些控件與其父組件FileExplorerAssistant通信。
擴展包括:
- GridControl擴展(GridControl)
- TreeList擴展(TreeList)
- Breadcrumb編輯擴展(breadcrumbed)
- 預覽面板擴展(PanelControl)
當單擊“Add…”智能標簽菜單操作時,組件會創建相應的control-extension對。如果需要,您可以單擊“Edit Extensions”智能標簽菜單操作來創建獨立的擴展,并將它們綁定到表單或UserControl上的控件。
TreeList擴展
TreeList擴展具有指定頂級節點列表的RootNodes集合。最初,這個集合只有一個節點——EnvironmentSpecialFolderNode,它允許用戶瀏覽一個:桌面、我的文檔、程序文件、字體和其他。該節點的初始值為“Desktop”,允許用戶瀏覽當前PC的整個本地存儲。
您可以修改此集合來添加其他節點:
PathNode指向單個本地存儲文件夾或驅動器,此對象的路徑存儲在節點的path屬性中。
C#:
// Scan for all partitions System.IO.DriveInfo[] driveList = System.IO.DriveInfo.GetDrives(); foreach (var drive in driveList) { // Select only logical fixed partitions if (drive.DriveType == System.IO.DriveType.Fixed && drive.IsReady) // Add each drive as a root node treeListExtension1.RootNodes.Add(new PathNode(drive.RootDirectory.ToString())); }
點擊復制
VB.NET:
' Scan for all partitions Dim driveList() As System.IO.DriveInfo = System.IO.DriveInfo.GetDrives() For Each drive In driveList ' Select only logical fixed partitions If drive.DriveType = System.IO.DriveType.Fixed AndAlso drive.IsReady Then ' Add each drive as a root node treeListExtension1.RootNodes.Add(New PathNode(drive.RootDirectory.ToString())) End If Next drive
點擊復制
GuidNode允許您添加具有 的特殊文件夾。
C#:
// Add the "Network" special folder GuidNode nodeNetwork = new GuidNode(new Guid("d20beec4-5ca8-4905-ae3b-bf251ea09b53")); nodeNetwork.AutoExpand = false; treeListExtension1.RootNodes.Add(nodeNetwork);
點擊復制
VB.NET:
' Add the "Network" special folder Dim nodeNetwork As New GuidNode(New Guid("d20beec4-5ca8-4905-ae3b-bf251ea09b53")) nodeNetwork.AutoExpand = False treeListExtension1.RootNodes.Add(nodeNetwork)
點擊復制
VirtualFolderNode和VirtualItemNode為自定義節點,您可以指定它們的標題和圖像,VirtualFolderNodes可以用子節點填充,使用這些節點創建本地存儲中不存在的自定義項。
GridControl擴展
GridControl擴展的兩個核心設置是:
- ViewMode——允許您在8種資源管理器樣式(磁貼、內容、大圖標等)之間進行選擇。
- CurrentPath——當前瀏覽的目錄。
BreadcrumbEdit擴展
CurrentPath是當前瀏覽的目錄。
預覽窗格擴展
集成預覽窗格,有了它,用戶可以在打開實際文件之前預覽與office相關的文檔(如DOCX、XLSX、CSV)、pdf、HTML文件、文本文件和圖像。
連接擴展
擴展之間不進行通信。例如,如果用戶在TreeList中選擇一個節點,則Data Grid不會反映此導航,需要根據自定義文件夾資源管理器的結構實現擴展之間的通信。
導航綁定
“navigation binding”是DevExpress.XtraDialogs.NavigationBinding類的一個對象,這些對象有兩個屬性:
- Source——指定跟蹤其導航的控件。
- Target ——指定應復制源控件導航的控件。
當存儲在FileExplorerAssistant.NavigationBindings集合中時,導航綁定將導航操作從該FileExplorerAssistant組件擁有的一個擴展傳輸到另一個擴展。
您可以在設計時添加導航綁定(在Visual Studio屬性網格中單擊“NavigationBindings”屬性旁邊的省略號按鈕)或在代碼中添加。在設計時,Collection Editor對話框檢查是否設置了Target和Source屬性,并突出顯示缺少這兩個設置中的任何一個的綁定。
您也可以在代碼中編輯導航綁定:
C#:
NavigationBinding nbGridToBreadcrumb = new NavigationBinding(); nbGridToBreadcrumb.Source = gridControlExtension1; nbGridToBreadcrumb.Target = breadCrumbExtension1; fileExplorerAssistant1.NavigationBindings.Add(nbGridToBreadcrumb);
點擊復制
VB.NET:
Dim nbGridToBreadcrumb As New NavigationBinding() nbGridToBreadcrumb.Source = gridControlExtension1 nbGridToBreadcrumb.Target = breadCrumbExtension1 fileExplorerAssistant1.NavigationBindings.Add(nbGridToBreadcrumb)
點擊復制
下面的例子演示了如何將預覽面板擴展綁定到網格控制擴展:
C#:
var gridExtension = assistant.Attach(grid, x => { x.CurrentPath = initialPath; }); var previewExtension = assistant.Attach(panel); assistant.NavigationBindings.Add(new NavigationBinding() { Source = gridExtension, Target = previewExtension });
點擊復制
VB.NET:
Dim gridExtension = assistant.Attach(grid, Sub(x) x.CurrentPath = initialPath) Dim previewExtension = assistant.Attach(panel) assistant.NavigationBindings.Add(New NavigationBinding() With {.Source = gridExtension, .Target = previewExtension})
點擊復制
導航事件
連接擴展的另一種方法是處理每個FileExplorerAssistant擴展可用的CurrentItemChanged事件,每當用戶在控件中選擇不同的項時,都會觸發此事件。處理CurrentItemChanged,如果您需要實現一個定制的擴展通信邏輯,而這個邏輯不能用導航綁定實現。
C#:
private void treeListExtension1_CurrentItemChanged(object sender, CurrentItemChangedEventArgs e) { // Update Data Grid and Breadcrumb when the Tree List selection changes gridControlExtension1.SetCurrentItem(e.CurrentItem); breadCrumbExtension1.SetCurrentItem(e.CurrentItem); }
點擊復制
VB.NET:
Private Sub treeListExtension1_CurrentItemChanged(ByVal sender As Object, ByVal e As CurrentItemChangedEventArgs) ' Update Data Grid and Breadcrumb when the Tree List selection changes gridControlExtension1.SetCurrentItem(e.CurrentItem) breadCrumbExtension1.SetCurrentItem(e.CurrentItem) End Sub
點擊復制
導航和編輯按鈕
FileExplorerAssistant擴展公開了一個API,允許您管理文件和文件夾。本節將演示如何使用該API來實現類似于DevExpress演示中“Two-Panel File Manager”中的操作按鈕。
- DoDefaultAction ——在選定的文件夾中導航,或者在與文件擴展名相關聯的默認程序中打開選定的文件(記事本用于.txt文件,照片用于.png文件,等等)。
- Rename ——重命名所選文件或文件夾。
- CopySelectedItem和 MoveSelectedItem ——將選定的文件或文件夾復制或移動到方法參數指定的位置,在下面的代碼中,所選文件被復制到另一個網格的當前打開的文件夾中。
C#:
gridControlExtension1.CopySelectedItem(gridControlExtension2.CurrentFolder);
點擊復制
VB.NET:
gridControlExtension1.CopySelectedItem(gridControlExtension2.CurrentFolder)
點擊復制
- CreateNewFolder ——在當前瀏覽的文件夾中創建一個新目錄。
- GoBack、GoForward、 GoUp——導航方法。
C#:
// Navigate to the parent folder gridControlExtension1.GoUp();
點擊復制
VB.NET:
' Navigate to the parent folder gridControlExtension1.GoUp()
點擊復制
- 以“Can”開頭的屬性返回是否可以對當前文件夾或文件執行相應的操作。例如,如果用戶瀏覽SpecialEnvironmentFolder.Desktop,它們無法導航到父文件夾(group方法不可用),并且canoup屬性返回false。
C#:
// Set the availability of a button that calls the Rename method btnRename.Enabled = gridControlExtension1.CanRename;
點擊復制
VB.NET:
' Set the availability of a button that calls the Rename method btnRename.Enabled = gridControlExtension1.CanRename
點擊復制
- SetCurrentPath and SetCurrentSpecialFolder——允許您瀏覽特定的文件夾或特殊的Windows文件夾。
C#:
breadCrumbExtension1.SetCurrentSpecialFolder(Environment.SpecialFolder.CommonStartMenu); // or breadCrumbExtension1.SetCurrentPath( Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu));
點擊復制
VB.NET:
breadCrumbExtension1.SetCurrentSpecialFolder(Environment.SpecialFolder.CommonStartMenu) ' or breadCrumbExtension1.SetCurrentPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu))
點擊復制
自定義層次結構
FileExplorerAssistant組件允許您創建解決方案,不僅可以瀏覽本地存儲上的文件夾,還可以瀏覽虛擬(自定義)層次結構。
要為Tree List控件創建自定義層次結構,請使用VirtualFolderNode和VirtualItemNode實例填充控件相關擴展的RootNodes集合。
VirtualFolderNode類對象充當“folders”,這些對象具有Nodes集合,您可以使用該集合用子文件夾或項填充它們。
C#:
VirtualFolderNode rootNode = new VirtualFolderNode("Root Node"); VirtualFolderNode childNode = new VirtualFolderNode("Child Node 1"); rootNode.ImageOptions.SvgImage = svgImageCollection1[0]; childNode.ImageOptions.SvgImage = svgImageCollection1[1]; // ... // Add more child nodes rootNode.Nodes.Add(childNode); treeListExtension1.RootNodes.Add(rootNode);
點擊復制
VB.NET:
Dim rootNode As VirtualFolderNode = New VirtualFolderNode("Root Node") Dim childNode As VirtualFolderNode = New VirtualFolderNode("Child Node 1") rootNode.ImageOptions.SvgImage = svgImageCollection1(0) childNode.ImageOptions.SvgImage = svgImageCollection1(1) ' ... ' Add more child nodes rootNode.Nodes.Add(childNode) treeListExtension1.RootNodes.Add(rootNode)
點擊復制
VirtualItemNode類對象作為“files”,這些對象不能嵌入其他文件夾或項,也不會顯示在樹列表中(類似于本地存儲文件)。
C#:
VirtualFolderNode rootNode = new VirtualFolderNode("Root Node"); rootNode.Nodes.Add(new VirtualFolderNode("Child Node 1")); ((VirtualFolderNode)rootNode.Nodes[0]).Nodes.Add(item1);
點擊復制
VB.NET:
Dim rootNode As New VirtualFolderNode("Root Node") rootNode.Nodes.Add(New VirtualFolderNode("Child Node 1")) CType(rootNode.Nodes(0), VirtualFolderNode).Nodes.Add(item1)
點擊復制
組合虛擬“folder”和“file”對象,根據需要創建自定義層次結構。
自定義預覽
下面的例子演示了如何預覽SVG文件:
C#:
using DevExpress.Dialogs.Core.Items; using DevExpress.Utils.Svg; using DevExpress.XtraEditors; using DevExpress.XtraEditors.Base.Controls.Preview; using DevExpress.XtraEditors.Controls; using System.Windows.Forms; var gridExtension = assistant.Attach(grid, x => { x.CurrentPath = initialPath; x.FilterString = "Svg files (*.svg)|*.svg"; }); var previewExtension = assistant.Attach(panel, x => { x.CustomizePreview += (s, e) => { if(e.Item.Extension.ToLower() == ".svg") e.CustomPreviewHandler = new SvgPreviewHandler(); }; }); assistant.NavigationBindings.Add(new NavigationBinding() { Source = gridExtension, Target = previewExtension }); //... public class SvgPreviewHandler : WinPreviewHandlerBase { SvgImage svgImage; public override bool Load(string file, ShellItem shellItem) { base.Load(file, shellItem); bool loaded = false; if(shellItem.Extension.ToLower() == ".svg") { try { this.svgImage = SvgImage.FromFile(file); loaded = true; } catch { } } return loaded; } public override Control CreatePreviewControl() { var picEdit = new PictureEdit(); picEdit.SvgImage = svgImage; picEdit.Enabled = false; picEdit.BorderStyle = BorderStyles.NoBorder; picEdit.Properties.SizeMode = PictureSizeMode.Squeeze; picEdit.Properties.UseDisabledStatePainter = false; return picEdit; } }
點擊復制
VB.NET:
Imports DevExpress.Dialogs.Core.Items Imports DevExpress.Utils.Svg Imports DevExpress.XtraEditors Imports DevExpress.XtraEditors.Base.Controls.Preview Imports DevExpress.XtraEditors.Controls Imports System.Windows.Forms Private gridExtension = assistant.Attach(grid, Sub(x) x.CurrentPath = initialPath x.FilterString = "Svg files (*.svg)|*.svg" End Sub) Private previewExtension = assistant.Attach(panel, Sub(x) AddHandler x.CustomizePreview, Sub(s, e) If e.Item.Extension.ToLower() = ".svg" Then e.CustomPreviewHandler = New SvgPreviewHandler() End If End Sub End Sub) assistant.NavigationBindings.Add(New NavigationBinding() With {.Source = gridExtension, .Target = previewExtension}) ' ... Public Class SvgPreviewHandler Inherits WinPreviewHandlerBase Private svgImage As SvgImage Public Overrides Function Load(ByVal file As String, ByVal shellItem As ShellItem) As Boolean MyBase.Load(file, shellItem) Dim loaded As Boolean = False If shellItem.Extension.ToLower() = ".svg" Then Try Me.svgImage = SvgImage.FromFile(file) loaded = True Catch End Try End If Return loaded End Function Public Overrides Function CreatePreviewControl() As Control Dim picEdit = New PictureEdit() picEdit.SvgImage = svgImage picEdit.Enabled = False picEdit.BorderStyle = BorderStyles.NoBorder picEdit.Properties.SizeMode = PictureSizeMode.Squeeze picEdit.Properties.UseDisabledStatePainter = False Return picEdit End Function End Class
點擊復制
自定義上下文菜單
在WinForms文件資源管理器助手組件中處理以下事件來自定義上下文菜單(添加新命令,隱藏/禁用命令等):
- ContextMenuShowing
- BeforeExecuteItemCommand
C#:
assistant.Attach(grid, x => { x.CurrentPath = initialPath; string customCommandName = "custom"; x.ContextMenuShowing += (s, e) => { e.MenuItems.AddCommand("Custom command", customCommandName); }; x.BeforeExecuteItemCommand += (s, e) => { if(e.CommandName == customCommandName) { XtraMessageBox.Show("Custom command executed"); e.Cancel = true; } }; });
點擊復制
VB.NET:
assistant.Attach(grid, Sub(x) x.CurrentPath = initialPath Dim customCommandName As String = "custom" AddHandler x.ContextMenuShowing, Sub(s, e) e.MenuItems.AddCommand("Custom command", customCommandName) End Sub AddHandler x.BeforeExecuteItemCommand, Sub(s, e) If e.CommandName = customCommandName Then XtraMessageBox.Show("Custom command executed") e.Cancel = True End If End Sub End Sub)
點擊復制