diff --git a/Sample Applications/WPF Application Samples.sln b/Sample Applications/WPF Application Samples.sln
index 17bc4c929..a8b25d905 100644
--- a/Sample Applications/WPF Application Samples.sln
+++ b/Sample Applications/WPF Application Samples.sln
@@ -1,19 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23103.0
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcentricRingsDemo", "ConcentricRingsDemo\ConcentricRingsDemo.csproj", "{0C7755BD-E5D1-4CB1-8271-445863408B5B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConcentricRingsDemo", "ConcentricRingsDemo\ConcentricRingsDemo.csproj", "{0C7755BD-E5D1-4CB1-8271-445863408B5B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CubeAnimationDemo", "CubeAnimationDemo\CubeAnimationDemo.csproj", "{8EF611EF-44AD-4871-9CF9-A80D501A1300}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CubeAnimationDemo", "CubeAnimationDemo\CubeAnimationDemo.csproj", "{8EF611EF-44AD-4871-9CF9-A80D501A1300}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomComboBox", "CustomComboBox\CustomComboBox.csproj", "{9E3EECAF-86CF-45CB-8ABB-01A850A308F0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomComboBox", "CustomComboBox\CustomComboBox.csproj", "{9E3EECAF-86CF-45CB-8ABB-01A850A308F0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataBindingDemo", "DataBindingDemo\DataBindingDemo.csproj", "{D56C3A49-C7A9-42E5-9C59-AF1670B08276}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataBindingDemo", "DataBindingDemo\DataBindingDemo.csproj", "{D56C3A49-C7A9-42E5-9C59-AF1670B08276}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropShadow", "DropShadow\DropShadow.csproj", "{5E760E96-A59B-491D-9FDC-70587AE24240}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropShadow", "DropShadow\DropShadow.csproj", "{5E760E96-A59B-491D-9FDC-70587AE24240}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditingExaminerDemo", "EditingExaminerDemo\EditingExaminerDemo.csproj", "{E689F47C-198B-4E3C-941D-81BD73D61B2C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EditingExaminerDemo", "EditingExaminerDemo\EditingExaminerDemo.csproj", "{E689F47C-198B-4E3C-941D-81BD73D61B2C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpenseItDemo", "ExpenseItDemo\ExpenseItDemo.csproj", "{D1729F17-99A5-45AF-AB38-72FA6ECCE609}"
EndProject
@@ -21,41 +21,43 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExpenseIt", "ExpenseIt", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditBoxControlLibrary", "EditBoxControlLibrary\EditBoxControlLibrary.csproj", "{558EEE03-6927-4FE6-AEB6-972769960849}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontDialogDemo", "FontDialog\FontDialogDemo.csproj", "{18DA881E-FE67-46E6-95E5-6FDC99331E2B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FontDialogDemo", "FontDialog\FontDialogDemo.csproj", "{18DA881E-FE67-46E6-95E5-6FDC99331E2B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeometryDesignerDemo", "GeometryDesignerDemo\GeometryDesignerDemo.csproj", "{FBA69105-5C42-44A4-82E6-0BF3BC09F2A5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeometryDesignerDemo", "GeometryDesignerDemo\GeometryDesignerDemo.csproj", "{FBA69105-5C42-44A4-82E6-0BF3BC09F2A5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphingCalculatorDemo", "GraphingCalculatorDemo\GraphingCalculatorDemo.csproj", "{1C45AF74-269B-4828-A054-6D0761304E61}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphingCalculatorDemo", "GraphingCalculatorDemo\GraphingCalculatorDemo.csproj", "{1C45AF74-269B-4828-A054-6D0761304E61}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HexSphereDemo", "HexSphereDemo\HexSphereDemo.csproj", "{48FC0038-9FDF-443C-B24B-9418C8956100}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HexSphereDemo", "HexSphereDemo\HexSphereDemo.csproj", "{48FC0038-9FDF-443C-B24B-9418C8956100}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LayoutTransitionsDemo", "LayoutTransitionsDemo\LayoutTransitionsDemo.csproj", "{9CB40026-7C2F-441F-B496-CDBB454AC309}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LayoutTransitionsDemo", "LayoutTransitionsDemo\LayoutTransitionsDemo.csproj", "{9CB40026-7C2F-441F-B496-CDBB454AC309}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogonScreenDemo", "LogonScreenDemo\LogonScreenDemo.csproj", "{20B6AAAA-E9A8-43B6-83A8-E855206269B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotepadDemo", "NotepadDemo\NotepadDemo.csproj", "{AC0A939B-050C-46B5-9EC8-F5349616AD03}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParticlesDemo", "ParticlesDemo\ParticlesDemo.csproj", "{F10AB8C9-CE19-44D6-BEA6-9EBA03850664}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParticlesDemo", "ParticlesDemo\ParticlesDemo.csproj", "{F10AB8C9-CE19-44D6-BEA6-9EBA03850664}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoFlipperDemo", "PhotoFlipperDemo\PhotoFlipperDemo.csproj", "{769F1C36-6975-4390-8D67-9E50A42D2755}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PhotoFlipperDemo", "PhotoFlipperDemo\PhotoFlipperDemo.csproj", "{769F1C36-6975-4390-8D67-9E50A42D2755}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStoreDemo", "PhotoStoreDemo\PhotoStoreDemo.csproj", "{D6567F46-7604-4714-9785-F99341AE5C81}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PhotoStoreDemo", "PhotoStoreDemo\PhotoStoreDemo.csproj", "{D6567F46-7604-4714-9785-F99341AE5C81}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StickyNotesDemo", "StickyNotesDemo\StickyNotesDemo.csproj", "{4CB08E17-0C15-4F66-8659-003D39E576BA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StickyNotesDemo", "StickyNotesDemo\StickyNotesDemo.csproj", "{4CB08E17-0C15-4F66-8659-003D39E576BA}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlidePuzzleDemo", "SlidePuzzleDemo\SlidePuzzleDemo.csproj", "{587E93FE-3686-4AE0-88A7-2E067AB0783A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlidePuzzleDemo", "SlidePuzzleDemo\SlidePuzzleDemo.csproj", "{587E93FE-3686-4AE0-88A7-2E067AB0783A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrafficAlertDemo", "TrafficAlertDemo\TrafficAlertDemo.csproj", "{0980E7C5-85A6-4451-B9E0-71EB4CDEC52A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorDemo", "CalculatorDemo\CalculatorDemo.csproj", "{5731865D-6685-47A7-8877-5DBAF39B54CD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalculatorDemo", "CalculatorDemo\CalculatorDemo.csproj", "{5731865D-6685-47A7-8877-5DBAF39B54CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoTextDemo", "VideoTextDemo\VideoTextDemo.csproj", "{8FD5A19E-9F9D-4F54-A2A6-4459A11E292A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoViewerDemo", "PhotoViewerDemo\PhotoViewerDemo.csproj", "{77372DB6-7B08-404D-B70E-69CF5ACD865C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PhotoViewerDemo", "PhotoViewerDemo\PhotoViewerDemo.csproj", "{77372DB6-7B08-404D-B70E-69CF5ACD865C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoViewerDemo", "VideoViewerDemo\VideoViewerDemo.csproj", "{439F91F2-9A8D-41EF-B9BB-D7CB2BCF3F10}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VideoViewerDemo", "VideoViewerDemo\VideoViewerDemo.csproj", "{439F91F2-9A8D-41EF-B9BB-D7CB2BCF3F10}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlToXamlDemo", "HtmlToXamlDemo\HtmlToXamlDemo.csproj", "{1AF5ED2C-BB8A-4B12-8CB5-8C8F2E838908}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlToXamlDemo", "HtmlToXamlDemo\HtmlToXamlDemo.csproj", "{1AF5ED2C-BB8A-4B12-8CB5-8C8F2E838908}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTreeView", "WpfTreeView\WpfTreeView.csproj", "{4DB0B7F2-36D1-4A9D-8EAF-DF4E4A0043E5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -167,6 +169,10 @@ Global
{1AF5ED2C-BB8A-4B12-8CB5-8C8F2E838908}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AF5ED2C-BB8A-4B12-8CB5-8C8F2E838908}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AF5ED2C-BB8A-4B12-8CB5-8C8F2E838908}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4DB0B7F2-36D1-4A9D-8EAF-DF4E4A0043E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4DB0B7F2-36D1-4A9D-8EAF-DF4E4A0043E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4DB0B7F2-36D1-4A9D-8EAF-DF4E4A0043E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4DB0B7F2-36D1-4A9D-8EAF-DF4E4A0043E5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -175,4 +181,7 @@ Global
{D1729F17-99A5-45AF-AB38-72FA6ECCE609} = {07258053-D6F1-4D8F-B3E4-A93423EFDF78}
{558EEE03-6927-4FE6-AEB6-972769960849} = {07258053-D6F1-4D8F-B3E4-A93423EFDF78}
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {CA7A4369-DB85-4780-872F-FD5AFEA01D0E}
+ EndGlobalSection
EndGlobal
diff --git a/Sample Applications/WpfTreeView/App.xaml b/Sample Applications/WpfTreeView/App.xaml
new file mode 100644
index 000000000..5327e5aa7
--- /dev/null
+++ b/Sample Applications/WpfTreeView/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/Sample Applications/WpfTreeView/App.xaml.cs b/Sample Applications/WpfTreeView/App.xaml.cs
new file mode 100644
index 000000000..99577bc9e
--- /dev/null
+++ b/Sample Applications/WpfTreeView/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace WpfTreeView
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/Sample Applications/WpfTreeView/AssemblyInfo.cs b/Sample Applications/WpfTreeView/AssemblyInfo.cs
new file mode 100644
index 000000000..8b5504ecf
--- /dev/null
+++ b/Sample Applications/WpfTreeView/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Sample Applications/WpfTreeView/HeaderToImageConverter.cs b/Sample Applications/WpfTreeView/HeaderToImageConverter.cs
new file mode 100644
index 000000000..d1464dc7b
--- /dev/null
+++ b/Sample Applications/WpfTreeView/HeaderToImageConverter.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace WpfTreeView
+{
+ ///
+ /// Converts a full path to a specific image type of a drive, folder or file.
+ ///
+
+ [ValueConversion(typeof(string), typeof(BitmapImage))]
+ public class HeaderToImageConverter : IValueConverter
+ {
+ public IDictionary KnownFiles { get; set; }
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ // Get the full Path
+ var path = (string)value;
+
+ // if the path is null, ignore
+ if (path == null)
+ return null;
+
+ // Get the name of the file/folder
+ var name = MainWindow.GetFileFolderName(path);
+
+ // By default, we presume an image
+ var image = "Images/file.png";
+
+ // If the name is blank, we presume it's a drive as we cannot have a blank file or folder name
+ if (string.IsNullOrEmpty(name))
+ image = "Images/drive.png";
+ else if (new FileInfo(path).Attributes.HasFlag(FileAttributes.Directory)) // checks if this path is a directory
+ image = "Images/folder-closed.png";
+ else if (KnownFiles != null && KnownFiles.ContainsKey(Path.GetExtension(path)))
+ return KnownFiles[Path.GetExtension(path)];
+
+ return new BitmapImage(new Uri($"pack://application:,,,/{image}"));
+
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Sample Applications/WpfTreeView/Images/c.png b/Sample Applications/WpfTreeView/Images/c.png
new file mode 100644
index 000000000..977a54e89
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/c.png differ
diff --git a/Sample Applications/WpfTreeView/Images/cpp.png b/Sample Applications/WpfTreeView/Images/cpp.png
new file mode 100644
index 000000000..cd4296f76
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/cpp.png differ
diff --git a/Sample Applications/WpfTreeView/Images/csharp.png b/Sample Applications/WpfTreeView/Images/csharp.png
new file mode 100644
index 000000000..e75aa963b
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/csharp.png differ
diff --git a/Sample Applications/WpfTreeView/Images/drive.png b/Sample Applications/WpfTreeView/Images/drive.png
new file mode 100644
index 000000000..377f43c83
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/drive.png differ
diff --git a/Sample Applications/WpfTreeView/Images/file.png b/Sample Applications/WpfTreeView/Images/file.png
new file mode 100644
index 000000000..d92b73b52
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/file.png differ
diff --git a/Sample Applications/WpfTreeView/Images/folder-closed.png b/Sample Applications/WpfTreeView/Images/folder-closed.png
new file mode 100644
index 000000000..e8a2bcfb1
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/folder-closed.png differ
diff --git a/Sample Applications/WpfTreeView/Images/folder-open.png b/Sample Applications/WpfTreeView/Images/folder-open.png
new file mode 100644
index 000000000..a51f879ab
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/folder-open.png differ
diff --git a/Sample Applications/WpfTreeView/Images/java.png b/Sample Applications/WpfTreeView/Images/java.png
new file mode 100644
index 000000000..97b5426a8
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/java.png differ
diff --git a/Sample Applications/WpfTreeView/Images/javascript.png b/Sample Applications/WpfTreeView/Images/javascript.png
new file mode 100644
index 000000000..06f906b87
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/javascript.png differ
diff --git a/Sample Applications/WpfTreeView/Images/json.png b/Sample Applications/WpfTreeView/Images/json.png
new file mode 100644
index 000000000..316907e1e
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/json.png differ
diff --git a/Sample Applications/WpfTreeView/Images/pdf.png b/Sample Applications/WpfTreeView/Images/pdf.png
new file mode 100644
index 000000000..fa0ace379
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/pdf.png differ
diff --git a/Sample Applications/WpfTreeView/Images/python.png b/Sample Applications/WpfTreeView/Images/python.png
new file mode 100644
index 000000000..19a271f6e
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/python.png differ
diff --git a/Sample Applications/WpfTreeView/Images/txt.png b/Sample Applications/WpfTreeView/Images/txt.png
new file mode 100644
index 000000000..51d43a1f5
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/txt.png differ
diff --git a/Sample Applications/WpfTreeView/Images/xlsx.png b/Sample Applications/WpfTreeView/Images/xlsx.png
new file mode 100644
index 000000000..6e9ac3e66
Binary files /dev/null and b/Sample Applications/WpfTreeView/Images/xlsx.png differ
diff --git a/Sample Applications/WpfTreeView/MainWindow.xaml b/Sample Applications/WpfTreeView/MainWindow.xaml
new file mode 100644
index 000000000..271d695a8
--- /dev/null
+++ b/Sample Applications/WpfTreeView/MainWindow.xaml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sample Applications/WpfTreeView/MainWindow.xaml.cs b/Sample Applications/WpfTreeView/MainWindow.xaml.cs
new file mode 100644
index 000000000..a996b2b62
--- /dev/null
+++ b/Sample Applications/WpfTreeView/MainWindow.xaml.cs
@@ -0,0 +1,1219 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace WpfTreeView
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ private Point _LastMousePos = new Point(0, 0);
+
+ #region Public Variables
+ private List _VisibleItems = new List();
+
+ public bool isCut = false;
+
+ ///
+ /// Store the Selected TreeView Item
+ ///
+ public Dictionary selectedItems =
+ new Dictionary();
+ private TreeViewItem lastSelectedItem = null;
+
+ ///
+ /// Dictionary for known files. If python is known, it assigns in logo as a python file.
+ ///
+ public IDictionary KnownFiles { get; set; }
+
+ ///
+ /// Store the mouse button clicked last time
+ ///
+ Point _lastMouseDown;
+
+ ///
+ /// Item which has been dragged
+ ///
+ IEnumerable draggedItem;
+
+ ///
+ /// Target location of the Item
+ ///
+ TreeViewItem _target;
+
+
+ #endregion
+
+ #region Copy Operation
+ public ICommand CopyCommand { get; set; }
+
+ public void ExecuteCopy(object sender)
+ {
+ // Clear Clipboard
+ Clipboard.Clear();
+
+ isCut = false;
+ var stringCollection = new StringCollection();
+
+ foreach (string path in selectedItems.Values)
+ {
+ stringCollection.Add(path);
+ }
+
+ if (stringCollection != null)
+ {
+ Clipboard.SetFileDropList(stringCollection);
+ (PasteCommand as RelayCommand).NotifyCanExecuteChanged(sender);
+ }
+ }
+
+ public bool CanCopy => selectedItems != null;
+ #endregion
+
+ #region Cut Operation
+
+ public ICommand CutCommand { get; set; }
+
+ public void ExecuteCut(object sender)
+ {
+ // Clear Clipboard
+ Clipboard.Clear();
+
+ isCut = true;
+ var stringCollection = new StringCollection();
+
+ foreach (string path in selectedItems.Values)
+ {
+ stringCollection.Add(path);
+ }
+
+ if (stringCollection != null)
+ {
+ Clipboard.SetFileDropList(stringCollection);
+ var temp = Clipboard.GetFileDropList();
+ (PasteCommand as RelayCommand).NotifyCanExecuteChanged(sender);
+ }
+ }
+
+ public bool CanCut => selectedItems != null;
+
+ #endregion
+
+ #region Paste Operation
+ public ICommand PasteCommand { get; set; }
+
+ ///
+ /// Execute Paste Operation
+ ///
+ ///
+ public void ExecutePaste(object sender)
+ {
+ // Get Tree View
+ var treeview = FolderView;
+
+ if (selectedItems.Count <= 0)
+ return;
+ try
+ {
+ foreach (var KV in selectedItems)
+ {
+ var path = KV.Value;
+ var item = KV.Key;
+ var files = Clipboard.GetFileDropList();
+ foreach (var file in files)
+ {
+ var newPath = Path.Combine(path, Path.GetFileName(file));
+ var backupPath = Path.ChangeExtension(newPath, Path.GetExtension(newPath) + ".bak");
+
+ if (File.Exists(newPath))
+ {
+ if (MessageBox.Show("The" + Path.GetFileName(newPath) + " already exist. Would you like to replace this file? ", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ // Replace the file
+ File.Delete(newPath);
+ File.Copy(file, newPath);
+ }
+ }
+ else
+ {
+ if (isCut)
+ File.Move(file, newPath);
+ else
+ File.Copy(file, newPath);
+ }
+ }
+ }
+ }
+ catch (Exception e) { MessageBox.Show("Paste Operation Failed : " + e.Message.ToString()); }
+
+ RefreshViews();
+ }
+ ///
+ /// If there are some files in clipboard and file count > 0 then allow paste operation
+ ///
+ public bool CanPaste => Clipboard.GetFileDropList() != null && Clipboard.GetFileDropList().Count > 0;
+ #endregion
+
+ #region Open Containing folder in Windows Explorer
+
+ ///
+ /// Command to open a file or folder containing folder
+ ///
+ public ICommand OpenExplorerCommand { get; set; }
+
+ ///
+ /// Execute command to open the file or folder containing folder
+ ///
+ ///
+ public void ExecuteOpeningExplorer(object sender)
+ {
+ if (selectedItems.Count != 1)
+ return;
+
+ // starts a new process of explorer.exe
+ Process.Start("explorer.exe", selectedItems.Values.FirstOrDefault().ToString());
+ }
+
+ ///
+ /// If only one is selected, then only open the folder otherwise not
+ ///
+ public bool CanOpenExplorer => selectedItems.Count == 1 && selectedItems.Values != null;
+
+ #endregion
+
+ #region Hard Refresh Command, recreates the treeview from scratch
+
+ ///
+ /// Hard refresh command
+ ///
+ public ICommand RefreshCommand { get; set; }
+
+ ///
+ /// Execute the hard refresh command
+ ///
+ ///
+ public void ExecuteRefresh(object sender)
+ {
+ FolderView.Items.Clear();
+ Window_Loaded(null, null);
+ }
+
+ ///
+ /// Can be refreshed without any condition
+ ///
+ public bool CanRefresh => true;
+
+ #endregion
+
+ #region Constructor
+ ///
+ /// Default Constructor
+ ///
+ public MainWindow()
+ {
+ // Copy and Paste command initialized
+ CopyCommand = new RelayCommand(ExecuteCopy, (_) => CanCopy);
+ PasteCommand = new RelayCommand(ExecutePaste, (_) => CanPaste);
+ CutCommand = new RelayCommand(ExecuteCut, (_) => CanCut);
+ OpenExplorerCommand = new RelayCommand(ExecuteOpeningExplorer, (_) => CanOpenExplorer);
+ RefreshCommand = new RelayCommand(ExecuteRefresh, (_) => CanRefresh);
+
+ InitializeComponent();
+
+ DataContext = this;
+
+ // Add known files such as .py into known Dictionary to recoginize that file
+ KnownFiles = new Dictionary();
+ KnownFiles.Add(".py", Resources["PythonIcon"] as BitmapImage);
+ KnownFiles.Add(".cs", Resources["CSharpIcon"] as BitmapImage);
+ KnownFiles.Add(".c", Resources["CIcon"] as BitmapImage);
+ KnownFiles.Add(".cpp", Resources["CppIcon"] as BitmapImage);
+ KnownFiles.Add(".java", Resources["JavaIcon"] as BitmapImage);
+ KnownFiles.Add(".js", Resources["JavascriptIcon"] as BitmapImage);
+ KnownFiles.Add(".txt", Resources["TextIcon"] as BitmapImage);
+ KnownFiles.Add(".json", Resources["JsonIcon"] as BitmapImage);
+ KnownFiles.Add(".xlsx", Resources["XslxIcon"] as BitmapImage);
+ KnownFiles.Add(".pdf", Resources["PdfIcon"] as BitmapImage);
+ (Resources["ImageConverter"] as HeaderToImageConverter).KnownFiles = KnownFiles;
+ }
+ #endregion
+
+ #region On Loaded
+ ///
+ /// When the application first opens
+ ///
+ /// Sender Object
+ /// Sender Object event
+ private void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ _VisibleItems.Clear();
+
+ // Get every logical drives on the machine
+ foreach (var drive in Directory.GetLogicalDrives())
+ {
+ // create a new item for it
+ var item = new TreeViewItem()
+ {
+ // set the header
+ Header = drive,
+ // Set the full path
+ Tag = drive
+ };
+ item.AllowDrop = true;
+ item.DragOver += MyTreeViewItem_DragOver;
+ item.MouseDown += MyTreeViewItem_MouseDown;
+ item.MouseMove += MyTreeViewItem_MouseMove;
+ item.Drop += MyTreeViewItem_Drop;
+
+
+ // Add a dummy item
+ item.Items.Add(null);
+
+ // Listen for the item being expanded
+ item.Expanded += Folder_Expanded;
+
+ // Add it to main tree view
+ FolderView.Items.Add(item);
+
+ _VisibleItems.Add(item);
+ }
+ }
+ #endregion
+
+ #region folder expanded
+ ///
+ /// When the folder is expanded
+ ///
+ ///
+ ///
+ private void Folder_Expanded(object sender, RoutedEventArgs e)
+ {
+ #region Initial Checks
+ var item = (TreeViewItem)sender;
+
+ // if the item only contains the dummy data
+ if (item.Items.Count != 1 && item.Items[0] != null)
+ return;
+
+ // clear dummy data
+ item.Items.Clear();
+
+ // Get full path
+ var fullPath = (string)item.Tag;
+
+ var itemIdx = _VisibleItems.IndexOf(item);
+
+ #endregion
+
+ #region Get Directories
+
+ // Create a blank list
+ var directories = new ObservableCollection();
+
+ // try and get directories from the folder
+ // ignoring any issues doing so
+ try
+ {
+ var dirs = Directory.GetDirectories(fullPath);
+
+ if (dirs.Length > 0)
+ foreach (var dir in dirs)
+ directories.Add(dir);
+ }
+ catch { }
+
+ foreach (var directoryPath in directories)
+ {
+ // Create Directory
+ var subItem = new TreeViewItem()
+ {
+ // Set header as folder name
+ Header = GetFileFolderName(directoryPath),
+ // And tag as full path
+ Tag = directoryPath
+ };
+ subItem.AllowDrop = true;
+
+ // Add dummy item so we can expand folder
+ subItem.Items.Add(null);
+ subItem.DragOver += MyTreeViewItem_DragOver;
+ subItem.MouseDown += MyTreeViewItem_MouseDown;
+ subItem.MouseMove += MyTreeViewItem_MouseMove;
+ subItem.Drop += MyTreeViewItem_Drop;
+
+ // Handle expanding
+ subItem.Expanded += Folder_Expanded;
+
+ // Add this item to parent
+ item.Items.Add(subItem);
+
+ _VisibleItems.Insert(++itemIdx, subItem);
+ }
+
+ #endregion
+
+ #region Get Files
+ // Create a blank list
+ var files = new ObservableCollection();
+
+ // try and get files f1rom the folder
+ // ignoreing any issues doing so
+ try
+ {
+ var fs = Directory.GetFiles(fullPath);
+
+ if (fs.Length > 0)
+ foreach (var f in fs)
+ files.Add(f);
+ }
+ catch { }
+
+ foreach (var filePath in files)
+ {
+ // Create file
+ var subItem = new TreeViewItem()
+ {
+ // Set header as file name
+ Header = GetFileFolderName(filePath),
+ // And tag as full path
+ Tag = filePath
+ };
+ subItem.AllowDrop = true;
+ subItem.DragOver += MyTreeViewItem_DragOver;
+ subItem.MouseDown += MyTreeViewItem_MouseDown;
+ subItem.MouseMove += MyTreeViewItem_MouseMove;
+ subItem.Drop += MyTreeViewItem_Drop;
+
+ // Add this item to parent
+ item.Items.Add(subItem);
+
+ _VisibleItems.Insert(++itemIdx, subItem);
+ }
+
+
+ #endregion
+ }
+
+ #endregion
+
+ #region Get File or Folder name
+ ///
+ /// Find the file or folder name from the full path
+ ///
+ ///
+ ///
+ 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 normalizePath = path.Replace('/', '\\');
+
+ // find the last back slash in the path
+ var lastIndex = normalizePath.LastIndexOf('\\');
+
+ // if we don't find a backslash, return the path itself
+ if (lastIndex <= 0)
+ return path;
+
+ // return name after the last back slash
+ return path.Substring(lastIndex + 1);
+ }
+
+ #endregion
+
+ #region Folder View Selecting items for copy paste operations
+ ///
+ /// Triggers if selection is changed in the folder view
+ ///
+ ///
+ ///
+ private void FolderView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs