/* 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 );
}
}
}