Back to Devexpress

How To: Create a File Explorer

windowsforms-17004-controls-and-libraries-editors-and-simple-controls-breadcrumb-edit-control-how-to-create-a-file-explorer.md

latest12.4 KB
Original Source

How To: Create a File Explorer

  • Nov 13, 2018
  • 5 minutes to read

This example demonstrates how to use the Breadcrumb Edit control to create a file navigation bar, similar to the one seen in Microsoft Windows Explorer. Two nodes (Root and Computer) are created at design-time as persistent nodes, always visible to an end-user. Their BreadCrumbNode.Persistent and BreadCrumbNode.PopulateOnDemand properties must be set to true. The Root node stores shortcuts to most important directories (Desktop, Windows, Program Files). The Computer node allows end-users to quickly navigate through local disks via related shortcuts. The Nodes tree is dynamically generated at runtime according to the current directories hierarchy. To do so, the RepositoryItemBreadCrumbEdit.ValidatePath, RepositoryItemBreadCrumbEdit.NewNodeAdding and RepositoryItemBreadCrumbEdit.QueryChildNodes events are handled.

View Example

csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.Utils.Menu;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;

namespace FileNavigator {
    public partial class Form1 : XtraForm {
        public static readonly int MaxEntitiesCount = 80;
        public Form1() {
            InitializeComponent();
            Initialize();
        }

        void myItem_Click(object sender, EventArgs e) {
            throw new NotImplementedException();
        }

        void Properties_QueryPopUp(object sender, CancelEventArgs e) {
            throw new NotImplementedException();
        }

        //Set the Breadcrumb Editor's initial path
        void Initialize() {
            breadCrumbEdit1.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            foreach (DriveInfo driveInfo in GetFixedDrives()) {
                breadCrumbEdit1.Properties.History.Add(new BreadCrumbHistoryItem(driveInfo.RootDirectory.ToString()));
            }
        }

        private void breadCrumbEdit1_Properties_NewNodeAdding(object sender, DevExpress.XtraEditors.BreadCrumbNewNodeAddingEventArgs e) {
            e.Node.PopulateOnDemand = true;
        }

        //Check whether or not the target path exists
        private void breadCrumbEdit1_Properties_ValidatePath(object sender, DevExpress.XtraEditors.BreadCrumbValidatePathEventArgs e) {
            if (!Directory.Exists(e.Path)) {
                e.ValidationResult = DevExpress.XtraEditors.BreadCrumbValidatePathResult.Cancel;
                return;
            }
            e.ValidationResult = DevExpress.XtraEditors.BreadCrumbValidatePathResult.CreateNodes;
        }

        private void breadCrumbEdit1_Properties_QueryChildNodes(object sender, DevExpress.XtraEditors.BreadCrumbQueryChildNodesEventArgs e) {
            //Add custom shortcuts to the 'Root' node
            if (string.Equals(e.Node.Caption, "Root", StringComparison.Ordinal)) {
                InitBreadCrumbRootNode(e.Node);
                return;
            }
            //Add local discs shortcuts to the 'Root' node
            if (string.Equals(e.Node.Caption, "Computer", StringComparison.Ordinal)) {
                InitBreadCrumbComputerNode(e.Node);
                return;
            }
            //Populate dynamic nodes
            string dir = e.Node.Path;
            if (!Directory.Exists(dir))
                return;
            string[] subDirs = GetSubFolders(dir);
            for (int i = 0; i < subDirs.Length; i++) {
                e.Node.ChildNodes.Add(CreateNode(subDirs[i]));
            }
        }

        void InitBreadCrumbRootNode(BreadCrumbNode node) {
            node.ChildNodes.Add(new BreadCrumbNode("Desktop", Environment.GetFolderPath(Environment.SpecialFolder.Desktop)));
            node.ChildNodes.Add(new BreadCrumbNode("Windows", Environment.GetFolderPath(Environment.SpecialFolder.Windows)));
            node.ChildNodes.Add(new BreadCrumbNode("Program Files", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)));
        }
        void InitBreadCrumbComputerNode(BreadCrumbNode node) {
            foreach (DriveInfo driveInfo in GetFixedDrives()) {
                node.ChildNodes.Add(new BreadCrumbNode(driveInfo.Name, driveInfo.RootDirectory));
            }
        }

        protected BreadCrumbNode CreateNode(string path) {
            string folderName = new DirectoryInfo(path).Name;
            return new BreadCrumbNode(folderName, folderName, true);
        }

        //Get the local drives list
        public static IEnumerable<DriveInfo> GetFixedDrives() {
            foreach (DriveInfo driveInfo in DriveInfo.GetDrives()) {
                if (driveInfo.DriveType != DriveType.Fixed) continue;
                yield return driveInfo;
            }
        }

        //Get all subfolders contained within the target directory
        public static string[] GetSubFolders(string rootDir) {
            string[] subDirs = GetSubDirs(rootDir);
            if (subDirs == null)
                return new string[0];
            if (subDirs.Length <= MaxEntitiesCount)
                return subDirs;
            string[] res = new string[MaxEntitiesCount];
            Array.Copy(subDirs, res, res.Length);
            return res;
        }

        //Get the names of the subdirectories
        public static string[] GetSubDirs(string dir) {
            string[] subDirs = null;
            try {
                subDirs = Directory.GetDirectories(dir, "*", SearchOption.TopDirectoryOnly);
            }
            catch { }
            return subDirs;
        }

        private void breadCrumbEdit1_PathChanged(object sender, BreadCrumbPathChangedEventArgs e) {
            label2.Text = breadCrumbEdit1.Path;
        }

        private void breadCrumbEdit1_Properties_PathChanged(object sender, BreadCrumbPathChangedEventArgs e) {

        }
    }
}
vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows.Forms
Imports DevExpress.Utils.Menu
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Repository

Namespace FileNavigator
    Public Partial Class Form1
        Inherits XtraForm
        Public Shared ReadOnly MaxEntitiesCount As Integer = 80
        Public Sub New()
            InitializeComponent()
            Initialize()
        End Sub

        Private Sub myItem_Click(ByVal sender As Object, ByVal e As EventArgs)
            Throw New NotImplementedException()
        End Sub

        Private Sub Properties_QueryPopUp(ByVal sender As Object, ByVal e As CancelEventArgs)
            Throw New NotImplementedException()
        End Sub

        'Set the Breadcrumb Editor's initial path
        Private Sub Initialize()
            breadCrumbEdit1.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            For Each driveInfo As DriveInfo In GetFixedDrives()
                breadCrumbEdit1.Properties.History.Add(New BreadCrumbHistoryItem(driveInfo.RootDirectory.ToString()))
            Next driveInfo
        End Sub

        Private Sub breadCrumbEdit1_Properties_NewNodeAdding(ByVal sender As Object, ByVal e As DevExpress.XtraEditors.BreadCrumbNewNodeAddingEventArgs) Handles breadCrumbEdit1.Properties.NewNodeAdding
            e.Node.PopulateOnDemand = True
        End Sub

        'Check whether or not the target path exists
        Private Sub breadCrumbEdit1_Properties_ValidatePath(ByVal sender As Object, ByVal e As DevExpress.XtraEditors.BreadCrumbValidatePathEventArgs) Handles breadCrumbEdit1.Properties.ValidatePath
            If (Not Directory.Exists(e.Path)) Then
                e.ValidationResult = DevExpress.XtraEditors.BreadCrumbValidatePathResult.Cancel
                Return
            End If
            e.ValidationResult = DevExpress.XtraEditors.BreadCrumbValidatePathResult.CreateNodes
        End Sub

        Private Sub breadCrumbEdit1_Properties_QueryChildNodes(ByVal sender As Object, ByVal e As DevExpress.XtraEditors.BreadCrumbQueryChildNodesEventArgs) Handles breadCrumbEdit1.Properties.QueryChildNodes
            'Add custom shortcuts to the 'Root' node
            If String.Equals(e.Node.Caption, "Root", StringComparison.Ordinal) Then
                InitBreadCrumbRootNode(e.Node)
                Return
            End If
            'Add local discs shortcuts to the 'Root' node
            If String.Equals(e.Node.Caption, "Computer", StringComparison.Ordinal) Then
                InitBreadCrumbComputerNode(e.Node)
                Return
            End If
            'Populate dynamic nodes
            Dim dir As String = e.Node.Path
            If (Not Directory.Exists(dir)) Then
                Return
            End If
            Dim subDirs As String() = GetSubFolders(dir)
            Dim i As Integer = 0
            Do While i < subDirs.Length
                e.Node.ChildNodes.Add(CreateNode(subDirs(i)))
                i += 1
            Loop
        End Sub

        Private Sub InitBreadCrumbRootNode(ByVal node As BreadCrumbNode)
            node.ChildNodes.Add(New BreadCrumbNode("Desktop", Environment.GetFolderPath(Environment.SpecialFolder.Desktop)))
            node.ChildNodes.Add(New BreadCrumbNode("Windows", Environment.GetFolderPath(Environment.SpecialFolder.Windows)))
            node.ChildNodes.Add(New BreadCrumbNode("Program Files", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)))
        End Sub
        Private Sub InitBreadCrumbComputerNode(ByVal node As BreadCrumbNode)
            For Each driveInfo As DriveInfo In GetFixedDrives()
                node.ChildNodes.Add(New BreadCrumbNode(driveInfo.Name, driveInfo.RootDirectory))
            Next driveInfo
        End Sub

        Protected Function CreateNode(ByVal path As String) As BreadCrumbNode
            Dim folderName As String = New DirectoryInfo(path).Name
            Return New BreadCrumbNode(folderName, folderName, True)
        End Function

        'Get the local drives list
        Public Shared Iterator Function GetFixedDrives() As IEnumerable(Of DriveInfo)
            For Each driveInfo As DriveInfo In DriveInfo.GetDrives()
                If driveInfo.DriveType <> DriveType.Fixed Then
                    Continue For
                End If
                Yield driveInfo
            Next driveInfo
        End Function

        'Get all subfolders contained within the target directory
        Public Shared Function GetSubFolders(ByVal rootDir As String) As String()
            Dim subDirs As String() = GetSubDirs(rootDir)
            If subDirs Is Nothing Then
                Return New String() {}
            End If
            If subDirs.Length <= MaxEntitiesCount Then
                Return subDirs
            End If
            Dim res As String() = New String(MaxEntitiesCount - 1) {}
            Array.Copy(subDirs, res, res.Length)
            Return res
        End Function

        'Get the names of the subdirectories
        Public Shared Function GetSubDirs(ByVal dir As String) As String()
            Dim subDirs As String() = Nothing
            Try
                subDirs = Directory.GetDirectories(dir, "*", SearchOption.TopDirectoryOnly)
            Catch
            End Try
            Return subDirs
        End Function

        Private Sub breadCrumbEdit1_PathChanged(ByVal sender As Object, ByVal e As BreadCrumbPathChangedEventArgs) Handles breadCrumbEdit1.PathChanged
            label2.Text = breadCrumbEdit1.Path
        End Sub

        Private Sub breadCrumbEdit1_Properties_PathChanged(ByVal sender As Object, ByVal e As BreadCrumbPathChangedEventArgs) Handles breadCrumbEdit1.Properties.PathChanged

        End Sub
    End Class
End Namespace