C# and WPF tutorial files

This commit is contained in:
Unknown
2017-05-29 21:01:07 +01:00
parent dfdd754362
commit 1cb838df3a
107 changed files with 5760 additions and 0 deletions

View File

@ -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); } }
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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) => { };
}
}

View File

@ -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
}
}

View File

@ -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)));
}
}
}

View File

@ -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
}
}