C# and WPF tutorial files
This commit is contained in:
@ -0,0 +1,23 @@
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about a directory item such as a drive, a file or a folder
|
||||
/// </summary>
|
||||
public class DirectoryItem
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of this item
|
||||
/// </summary>
|
||||
public DirectoryItemType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The absolute path to this item
|
||||
/// </summary>
|
||||
public string FullPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this directory item
|
||||
/// </summary>
|
||||
public string Name { get { return this.Type == DirectoryItemType.Drive ? this.FullPath : DirectoryStructure.GetFileFolderName(this.FullPath); } }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of a directory item
|
||||
/// </summary>
|
||||
public enum DirectoryItemType
|
||||
{
|
||||
/// <summary>
|
||||
/// A logical drive
|
||||
/// </summary>
|
||||
Drive,
|
||||
/// <summary>
|
||||
/// A phyiscal file
|
||||
/// </summary>
|
||||
File,
|
||||
/// <summary>
|
||||
/// A folder
|
||||
/// </summary>
|
||||
Folder
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to query information about directories
|
||||
/// </summary>
|
||||
public static class DirectoryStructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all logical drives on the computer
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<DirectoryItem> GetLogicalDrives()
|
||||
{
|
||||
// Get every logical drive on the machine
|
||||
return Directory.GetLogicalDrives().Select(drive => new DirectoryItem { FullPath = drive, Type = DirectoryItemType.Drive }).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directories top-level content
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path to the directory</param>
|
||||
/// <returns></returns>
|
||||
public static List<DirectoryItem> GetDirectoryContents(string fullPath)
|
||||
{
|
||||
// Create empty list
|
||||
var items = new List<DirectoryItem>();
|
||||
|
||||
#region Get Folders
|
||||
|
||||
// Try and get directories from the folder
|
||||
// ignoring any issues doing so
|
||||
try
|
||||
{
|
||||
var dirs = Directory.GetDirectories(fullPath);
|
||||
|
||||
if (dirs.Length > 0)
|
||||
items.AddRange(dirs.Select(dir => new DirectoryItem { FullPath = dir, Type = DirectoryItemType.Folder }));
|
||||
}
|
||||
catch { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Files
|
||||
|
||||
// Try and get files from the folder
|
||||
// ignoring any issues doing so
|
||||
try
|
||||
{
|
||||
var fs = Directory.GetFiles(fullPath);
|
||||
|
||||
if (fs.Length > 0)
|
||||
items.AddRange(fs.Select(file => new DirectoryItem { FullPath = file, Type = DirectoryItemType.File }));
|
||||
}
|
||||
catch { }
|
||||
|
||||
#endregion
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Find the file or folder name from a full path
|
||||
/// </summary>
|
||||
/// <param name="path">The full path</param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileFolderName(string path)
|
||||
{
|
||||
// If we have no path, return empty
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return string.Empty;
|
||||
|
||||
// Make all slashes back slashes
|
||||
var normalizedPath = path.Replace('/', '\\');
|
||||
|
||||
// Find the last backslash in the path
|
||||
var lastIndex = normalizedPath.LastIndexOf('\\');
|
||||
|
||||
// If we don't find a backslash, return the path itself
|
||||
if (lastIndex <= 0)
|
||||
return path;
|
||||
|
||||
// Return the name after the last back slash
|
||||
return path.Substring(lastIndex + 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using PropertyChanged;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// A base view model that fires Property Changed events as needed
|
||||
/// </summary>
|
||||
[ImplementPropertyChanged]
|
||||
public class BaseViewModel : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// The event that is fired when any child property changes its value
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic command that runs an Action
|
||||
/// </summary>
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
/// <summary>
|
||||
/// The action to run
|
||||
/// </summary>
|
||||
private Action mAction;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Events
|
||||
|
||||
/// <summary>
|
||||
/// The event thats fired when the <see cref="CanExecute(object)"/> value has changed
|
||||
/// </summary>
|
||||
public event EventHandler CanExecuteChanged = (sender, e) => { };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public RelayCommand(Action action)
|
||||
{
|
||||
mAction = action;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command Methods
|
||||
|
||||
/// <summary>
|
||||
/// A relay command can always execute
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns></returns>
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the commands Action
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
mAction();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// A view model for each directory item
|
||||
/// </summary>
|
||||
public class DirectoryItemViewModel : BaseViewModel
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// The type of this item
|
||||
/// </summary>
|
||||
public DirectoryItemType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The full path to the item
|
||||
/// </summary>
|
||||
public string FullPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this directory item
|
||||
/// </summary>
|
||||
public string Name { get { return this.Type == DirectoryItemType.Drive ? this.FullPath : DirectoryStructure.GetFileFolderName(this.FullPath); } }
|
||||
|
||||
/// <summary>
|
||||
/// A list of all children contained inside this item
|
||||
/// </summary>
|
||||
public ObservableCollection<DirectoryItemViewModel> Children { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this item can be expanded
|
||||
/// </summary>
|
||||
public bool CanExpand { get { return this.Type != DirectoryItemType.File; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current item is expanded or not
|
||||
/// </summary>
|
||||
public bool IsExpanded
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Children?.Count(f => f != null) > 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
// If the UI tells us to expand...
|
||||
if (value == true)
|
||||
// Find all children
|
||||
Expand();
|
||||
// If the UI tells us to close
|
||||
else
|
||||
this.ClearChildren();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Commands
|
||||
|
||||
/// <summary>
|
||||
/// The command to expand this item
|
||||
/// </summary>
|
||||
public ICommand ExpandCommand { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path of this item</param>
|
||||
/// <param name="type">The type of item</param>
|
||||
public DirectoryItemViewModel(string fullPath, DirectoryItemType type)
|
||||
{
|
||||
// Create commands
|
||||
this.ExpandCommand = new RelayCommand(Expand);
|
||||
|
||||
// Set path and type
|
||||
this.FullPath = fullPath;
|
||||
this.Type = type;
|
||||
|
||||
// Setup the children as needed
|
||||
this.ClearChildren();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Removes all children from the list, adding a dummy item to show the expand icon if required
|
||||
/// </summary>
|
||||
private void ClearChildren()
|
||||
{
|
||||
// Clear items
|
||||
this.Children = new ObservableCollection<DirectoryItemViewModel>();
|
||||
|
||||
// Show the expand arrow if we are not a file
|
||||
if (this.Type != DirectoryItemType.File)
|
||||
this.Children.Add(null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Expands this directory and finds all children
|
||||
/// </summary>
|
||||
private void Expand()
|
||||
{
|
||||
// We cannot expand a file
|
||||
if (this.Type == DirectoryItemType.File)
|
||||
return;
|
||||
|
||||
// Find all children
|
||||
var children = DirectoryStructure.GetDirectoryContents(this.FullPath);
|
||||
this.Children = new ObservableCollection<DirectoryItemViewModel>(
|
||||
children.Select(content => new DirectoryItemViewModel(content.FullPath, content.Type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace WpfTreeView
|
||||
{
|
||||
/// <summary>
|
||||
/// The view model for the applications main Directory view
|
||||
/// </summary>
|
||||
public class DirectoryStructureViewModel : BaseViewModel
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// A list of all directories on the machine
|
||||
/// </summary>
|
||||
public ObservableCollection<DirectoryItemViewModel> Items { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public DirectoryStructureViewModel()
|
||||
{
|
||||
// Get the logical drives
|
||||
var children = DirectoryStructure.GetLogicalDrives();
|
||||
|
||||
// Create the view models from the data
|
||||
this.Items = new ObservableCollection<DirectoryItemViewModel>(
|
||||
children.Select(drive => new DirectoryItemViewModel(drive.FullPath, DirectoryItemType.Drive)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user