A File Explore Clone : File Explore « GUI Windows Forms « C# / CSharp Tutorial






/* Quote from 

Programming .NET Windows Applications

By Jesse Liberty, Dan Hurwitz
First Edition October 2003 
Pages: 1246 (More details)
*/

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Diagnostics;    //  for Process.Start

namespace csExplorerClone
{
  public class Form1 : System.Windows.Forms.Form
  {
    private System.Windows.Forms.Splitter splitter1;
    private System.Windows.Forms.ListView lv;
    private System.Windows.Forms.TreeView tvw;
    private System.Windows.Forms.MainMenu mainMenu1;
    private System.Windows.Forms.MenuItem menuItem1;
    private System.Windows.Forms.MenuItem mnuSmallIcons;
    private System.Windows.Forms.MenuItem mnuLargeIcons;
    private System.Windows.Forms.MenuItem mnuList;
    private System.Windows.Forms.MenuItem mnuDetails;
    
    public enum ColumnType
    {
      Alpha,
      Numeric,
      DateTimeValue
    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;

    public Form1()
    {
      InitializeComponent();

      //  Similar to TreeViews program
      //  Use an array to add filenames to the ImageLists
      String[] arFiles = {
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\icons\computer\form.ico",
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\icons\win95\clsdfold.ico", 
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\icons\win95\openfold.ico", 
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\bitmaps\assorted\happy.bmp",
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\bitmaps\outline\NoMask\doc.bmp",
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\bitmaps\outline\NoMask\exe.bmp",
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\bitmaps\outline\NoMask\txt.bmp",
        @"C:\Program Files\Microsoft Visual Studio .NET\Common7\" + 
                @"Graphics\bitmaps\outline\NoMask\windoc.bmp"
        };
      ImageList imgListSmall = new ImageList();  //  default size 16x16
      ImageList imgListLarge = new ImageList();
      imgListLarge.ImageSize = new Size(32,32);
      for (int i = 0; i < arFiles.Length; i++)
      {
        imgListSmall.Images.Add(Image.FromFile(arFiles[i]));    
        imgListLarge.Images.Add(Image.FromFile(arFiles[i]));    
      }

      tvw.Size = new Size(ClientSize.Width / 3, ClientSize.Height);
      tvw.BackColor = Color.Moccasin;
      tvw.HideSelection = false;  
      tvw.ImageList = imgListSmall;
      tvw.ImageIndex = 1;
      tvw.SelectedImageIndex = 2;
      //  End similar to TreeViews program

      lv.BackColor = Color.PaleTurquoise;
      lv.ForeColor = Color.DarkBlue;
      lv.HideSelection = false;
      lv.SmallImageList = imgListSmall;
      lv.LargeImageList = imgListLarge;
      lv.View = View.SmallIcon;
      lv.Activation = ItemActivation.Standard;  // default
      lv.MultiSelect = true;      // default
      lv.HoverSelection = false;    // default
      lv.Sorting = SortOrder.None;  // default
      lv.AllowColumnReorder = true;
      lv.FullRowSelect = true;
      lv.GridLines = true;
      lv.HeaderStyle = ColumnHeaderStyle.Clickable;    // default
      lv.LabelEdit = true;
      
      //  Similar to TreeViews program
      //  Fill the directory tree
      FillDirectoryTree();
    }

    //  These 3 methods essentially same as in TreeViews program
    private void FillDirectoryTree()
    {
      //  Populate with the contents of the local hard drive.

      //  Suppress redraw until tree view is complete
      tvw.BeginUpdate();

           //  First clear all the nodes.
      tvw.Nodes.Clear();

      //  Get the logical drives and put them into the root nodes.
      //  Fill an array with all the logical drives on the machine.
      string[] strDrives = Environment.GetLogicalDrives();

      //  Iterate through the drives, adding them to the tree.
      //  Use a try/catch block, so if a drive is not ready, 
      //  e.g. an empty floppy or CD, it will not be added to the tree.
            foreach (string rootDirectoryName in strDrives)
           {
        try 
        {
          //  Find all the first level subdirectories.
          //  If the drive is not ready, this will throw an 
          //  exception, which will have the effect of 
          //  skipping that drive.
          Directory.GetDirectories(rootDirectoryName);

          //  Create a node for each root directory
          TreeNode ndRoot = new TreeNode(rootDirectoryName);

          //  Add the node to the tree
          tvw.Nodes.Add(ndRoot);
 
          //  Set colors based on Index property.
           //  Index not set until after node added to collection.
          if (ndRoot.Index % 2 == 0)
          {
            ndRoot.BackColor = Color.LightYellow;
            ndRoot.ForeColor = Color.Green;
          }

          //  Add subdirectory nodes.
          //  Hard code getFileNames to false.
          GetSubDirectoryNodes(ndRoot, false);
        }
        catch  (System.IO.IOException)
        {
          //  let it through
              }
        catch  (Exception e)
        {
                //  Catch any other errors.
          MessageBox.Show(e.Message);
              }
      }
         
          tvw.EndUpdate();
         
    }      //  close FillDirectoryTree

    private void GetSubDirectoryNodes(TreeNode parentNode, 
                          bool getFileNames)
    {
      //  Exit this method if the node is not a directory.
      DirectoryInfo di = new DirectoryInfo(parentNode.FullPath);
      if ((di.Attributes & FileAttributes.Directory) == 0)
      {
        return;
      }

           //  Clear all the nodes in this node.
      parentNode.Nodes.Clear();

      //  Get an array of strings containing all the subdirectories in the parent node.
      string[] arSubs = Directory.GetDirectories(parentNode.FullPath);

      //  Add a child node for each subdirectory.
      foreach (string subDir in arSubs)
      {
              DirectoryInfo dirInfo = new DirectoryInfo(subDir);
              // do not show hidden folders
              if ((dirInfo.Attributes & FileAttributes.Hidden)!= 0)
              {
                 continue;
              }

        TreeNode subNode = new TreeNode(dirInfo.Name);
        parentNode.Nodes.Add(subNode);
            
        //  Set colors based on Index property.
        if (subNode.Index % 2 == 0)
          subNode.BackColor = Color.LightPink;
      }

//  This section of code is never called in this program.  Vestigial from TreeViews.cs
//      if (getFileNames)
//      {
//              //  Get any files for this node.
//              string[] files = Directory.GetFiles(parentNode.FullPath);
//
//              // After placing the nodes, 
//              // now place the files in that subdirectory.
//              foreach (string str in files)
//              {
//          FileInfo fi = new FileInfo(str);
//          TreeNode fileNode = new TreeNode(fi.Name);
//          parentNode.Nodes.Add(fileNode);
//
//          //  Set the icon
//          fileNode.ImageIndex = 0;
//          fileNode.SelectedImageIndex = 3;
//
//          //  Set colors based on Index property.
//          if (fileNode.Index % 2 == 0)
//            fileNode.BackColor = Color.LightGreen;
//              }
//      }
    }  // close GetSubDirectoryNodes

    private void tvw_BeforeExpand(object sender, 
                  TreeViewCancelEventArgs e)
    {
      tvw.BeginUpdate();
      foreach (TreeNode tn in e.Node.Nodes)
      {
        GetSubDirectoryNodes(tn, false);
      }
      tvw.EndUpdate();      
    }    

    
    // This populates the list view after a tree node is selected
    private void tvw_AfterSelect(object sender, 
                  TreeViewEventArgs e)
    {
      lv.Clear();
      lv.BeginUpdate();
      
      DirectoryInfo di = new DirectoryInfo(e.Node.FullPath);
      FileSystemInfo[] afsi = di.GetFileSystemInfos();
      foreach (FileSystemInfo fsi in afsi)
      {
        ListViewItem lvi = new ListViewItem(fsi.Name);
        
        if ((fsi.Attributes & FileAttributes.Directory) != 0)
        {
          lvi.ImageIndex = 1;
          lvi.SubItems.Add("");      // Bytes subitem
        }
        else
        {
          switch(fsi.Extension.ToUpper())
          {
            case ".DOC" :
              lvi.ImageIndex = 4;
              break;
            case ".EXE" :
              lvi.ImageIndex = 5;
              break;
            case ".TXT" :
              lvi.ImageIndex = 6;
              break;
            default :
              lvi.ImageIndex = 7;
              break;
          }
          //  Bytes subitem, w/ commas
          //  Cast FileSystemInfo object to FileInfo object so the 
          //    size can be obtained.
          lvi.SubItems.Add(((FileInfo)fsi).Length.ToString("N0"));
        }

        //  Add the remaining subitems to the ListViewItem
        lvi.SubItems.Add(fsi.Extension);            // type
        lvi.SubItems.Add(fsi.LastWriteTime.ToString());  // modified

        //  Build up the Attributes string
        string strAtt = "";
        if ((fsi.Attributes & FileAttributes.ReadOnly) != 0)
          strAtt += "R";
        if ((fsi.Attributes & FileAttributes.Hidden) != 0)
          strAtt += "H";
        if ((fsi.Attributes & FileAttributes.System) != 0)
          strAtt += "S";
        if ((fsi.Attributes & FileAttributes.Archive) != 0)
          strAtt += "A";
        lvi.SubItems.Add(strAtt);        // attributes

        lv.Items.Add(lvi);
      }  //  end foreach
      
      lv.Columns.Add("Name", 150, HorizontalAlignment.Left);
      lv.Columns.Add("Bytes", 75, HorizontalAlignment.Right);
      lv.Columns.Add("Ext.", 50, HorizontalAlignment.Left);
      lv.Columns.Add("Modified", 125, HorizontalAlignment.Left);
      lv.Columns.Add("Attrib.", 50, HorizontalAlignment.Left);
      
      lv.EndUpdate();
    }                //  close tvw_AfterSelect

    
    private void mnuView_Click(object sender, EventArgs e)
    {
      MenuItem mnu = (MenuItem)sender;
      switch (mnu.Mnemonic.ToString())
      {
        case "L"  :    //  Large Icons  
          lv.View = View.LargeIcon;
          break;
        case "S"  :    //  Small Icons
          lv.View = View.SmallIcon;
          break;
        case "T" :    //  List view
          lv.View = View.List;
          break;
        case "D" :    //  Detail view
          lv.View = View.Details;
          break;
      }
    }

    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if (components != null) 
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }

    #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.tvw = new System.Windows.Forms.TreeView();
      this.splitter1 = new System.Windows.Forms.Splitter();
      this.lv = new System.Windows.Forms.ListView();
      this.mainMenu1 = new System.Windows.Forms.MainMenu();
      this.menuItem1 = new System.Windows.Forms.MenuItem();
      this.mnuSmallIcons = new System.Windows.Forms.MenuItem();
      this.mnuLargeIcons = new System.Windows.Forms.MenuItem();
      this.mnuList = new System.Windows.Forms.MenuItem();
      this.mnuDetails = new System.Windows.Forms.MenuItem();
      this.SuspendLayout();
      // 
      // tvw
      // 
      this.tvw.Dock = System.Windows.Forms.DockStyle.Left;
      this.tvw.ImageIndex = -1;
      this.tvw.Name = "tvw";
      this.tvw.SelectedImageIndex = -1;
      this.tvw.Size = new System.Drawing.Size(168, 600);
      this.tvw.TabIndex = 0;
      this.tvw.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvw_AfterSelect);
      this.tvw.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvw_BeforeExpand);
      // 
      // splitter1
      // 
      this.splitter1.Location = new System.Drawing.Point(168, 0);
      this.splitter1.Name = "splitter1";
      this.splitter1.Size = new System.Drawing.Size(3, 600);
      this.splitter1.TabIndex = 1;
      this.splitter1.TabStop = false;
      // 
      // lv
      // 
      this.lv.Dock = System.Windows.Forms.DockStyle.Fill;
      this.lv.Location = new System.Drawing.Point(171, 0);
      this.lv.Name = "lv";
      this.lv.Size = new System.Drawing.Size(429, 600);
      this.lv.TabIndex = 2;
      this.lv.ItemActivate += new System.EventHandler(this.lv_ItemActivate);
      this.lv.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lv_AfterLabelEdit);
      this.lv.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lv_ColumnClick);
      this.lv.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lv_BeforeLabelEdit);
      // 
      // mainMenu1
      // 
      this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                       this.menuItem1});
      // 
      // menuItem1
      // 
      this.menuItem1.Index = 0;
      this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                       this.mnuSmallIcons,
                                                       this.mnuLargeIcons,
                                                       this.mnuList,
                                                       this.mnuDetails});
      this.menuItem1.Text = "&View";
      // 
      // mnuSmallIcons
      // 
      this.mnuSmallIcons.Index = 0;
      this.mnuSmallIcons.Text = "&Small Icons";
      this.mnuSmallIcons.Click += new System.EventHandler(this.mnuView_Click);
      // 
      // mnuLargeIcons
      // 
      this.mnuLargeIcons.Index = 1;
      this.mnuLargeIcons.Text = "&Large Icons";
      this.mnuLargeIcons.Click += new System.EventHandler(this.mnuView_Click);
      // 
      // mnuList
      // 
      this.mnuList.Index = 2;
      this.mnuList.Text = "Lis&t";
      this.mnuList.Click += new System.EventHandler(this.mnuView_Click);
      // 
      // mnuDetails
      // 
      this.mnuDetails.Index = 3;
      this.mnuDetails.Text = "&Details";
      this.mnuDetails.Click += new System.EventHandler(this.mnuView_Click);
      // 
      // Form1
      // 
      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
      this.ClientSize = new System.Drawing.Size(600, 600);
      this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                               this.lv,
                                               this.splitter1,
                                               this.tvw});
      this.Menu = this.mainMenu1;
      this.Name = "Form1";
      this.Text = "Form1";
      this.ResumeLayout(false);

    }
    #endregion

    [STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }


    private void lv_ItemActivate(object sender, EventArgs e)
    {
      ListView lv = (ListView)sender;
      foreach (ListViewItem lvi in lv.SelectedItems)
      {
        try
        {
          Process.Start(tvw.SelectedNode.FullPath + "\\" + lvi.Text);
        }
        catch
        {
        }
      }
    }

    public class SortListViewItems : IComparer    //  nested class
    {
      int columnIndex;
      ColumnType columnType;
      bool isAscending;
      public static Boolean isNameAscending = true;
      public static Boolean isBytesAscending = false;
      public static Boolean isExtAscending = false;
      public static Boolean isModifiedAscending = false;
      public static Boolean isAttribAscending = false;
      
      public SortListViewItems(int columnIndex, 
                      ColumnType columnType, 
                      bool isAscending)
      {
        this.columnIndex = columnIndex;
        this.columnType = columnType;
        this.isAscending = isAscending;
      }
    
      public int Compare(object x, object y)
      {
        string strFirst = 
          ((ListViewItem)x).SubItems[columnIndex].Text;
        string strSecond = 
          ((ListViewItem)y).SubItems[columnIndex].Text;
        
        switch (columnType)
        {
          case ColumnType.Alpha :
            if (isAscending)
              return strFirst.CompareTo(strSecond);
            else
              return strSecond.CompareTo(strFirst);
            
          case ColumnType.DateTimeValue :
            if (isAscending)
              return 
                DateTime.Parse(strFirst).
                  CompareTo(DateTime.Parse(strSecond));
            else
              return 
                DateTime.Parse(strSecond).
                  CompareTo(DateTime.Parse(strFirst));
            
          case ColumnType.Numeric :
            //  Special case blank byte values.
            if (strFirst == "")
              strFirst = "-1";
            if (strSecond == "")
              strSecond = "-1";
          
            if (isAscending)
              return 
                Double.Parse(strFirst).
                  CompareTo(Double.Parse(strSecond));
            else
              return 
                Double.Parse(strSecond).
                  CompareTo(Double.Parse(strFirst));
            
          default:
            return 0;      
        }      //  close switch block  
      }        //  close Compare method
    }          //  close nested SortListViewItems class

    private void lv_ColumnClick(object sender, ColumnClickEventArgs e)
    {
      ColumnType columnType;
      bool isAscending = true;
      string strName = ((ListView)sender).Columns[e.Column].Text;
      switch(strName)
      {
        case "Name": 
          columnType = ColumnType.Alpha;
          SortListViewItems.isNameAscending = 
              !SortListViewItems.isNameAscending;
          isAscending = SortListViewItems.isNameAscending;
          break;
        case "Bytes": 
          columnType = ColumnType.Numeric;
          SortListViewItems.isBytesAscending = 
              !SortListViewItems.isBytesAscending;
          isAscending = SortListViewItems.isBytesAscending;
          break;
        case "Ext.": 
          columnType = ColumnType.Alpha;
          SortListViewItems.isExtAscending = 
              !SortListViewItems.isExtAscending;
          isAscending = SortListViewItems.isExtAscending;
          break;
        case "Modified": 
          columnType = ColumnType.DateTimeValue;
          SortListViewItems.isModifiedAscending = 
              !SortListViewItems.isModifiedAscending;
          isAscending = SortListViewItems.isModifiedAscending;
          break;
        case "Attrib.": 
          columnType = ColumnType.Alpha;
          SortListViewItems.isAttribAscending = 
              !SortListViewItems.isAttribAscending;
          isAscending = SortListViewItems.isAttribAscending;
          break;
        default:
          columnType = ColumnType.Alpha;
          break;
      }
      
      lv.ListViewItemSorter = new SortListViewItems(e.Column, 
                                    columnType, 
                                    isAscending);
      lv.Sort();
    }            // close lv_ColumnClick

    private void lv_BeforeLabelEdit(object sender, LabelEditEventArgs e)
    {
      MessageBox.Show("About to edit\n" +
        "Item:" + e.Item.ToString() + "\n" +
        "label:" + e.Label );
    }

    private void lv_AfterLabelEdit(object sender, LabelEditEventArgs e)
    {
      MessageBox.Show("After edit\n" +
        "Item:" + e.Item.ToString() + "\n" +
        "label:" + e.Label );
    }
  }
}








23.76.File Explore
23.76.1.A File Explore Clone