diff --git a/src/Gemini/Gemini.csproj b/src/Gemini/Gemini.csproj
index f6148ae6..5cfbb94d 100644
--- a/src/Gemini/Gemini.csproj
+++ b/src/Gemini/Gemini.csproj
@@ -187,6 +187,7 @@
SettingsView.xaml
+
diff --git a/src/Gemini/Modules/Shell/Behaviors/DropFilesBehavior.cs b/src/Gemini/Modules/Shell/Behaviors/DropFilesBehavior.cs
new file mode 100644
index 00000000..aaf2409f
--- /dev/null
+++ b/src/Gemini/Modules/Shell/Behaviors/DropFilesBehavior.cs
@@ -0,0 +1,105 @@
+using Caliburn.Micro;
+using Gemini.Framework;
+using Gemini.Framework.Commands;
+using Gemini.Framework.Services;
+using Gemini.Modules.Shell.Commands;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace Gemini.Modules.Shell.Behaviors
+{
+ ///
+ /// Attached behaviour to implement the drop event
+ /// source: http://social.msdn.microsoft.com/Forums/de-DE/wpf/thread/21bed380-c485-44fb-8741-f9245524d0ae
+ /// http://stackoverflow.com/questions/1034374/drag-and-drop-in-mvvm-with-scatterview
+ ///
+ public class DropFilesBehavior : DependencyObject
+ {
+ public static readonly DependencyProperty AllowOpenProperty = DependencyProperty.RegisterAttached(
+ "AllowOpen",
+ typeof(bool),
+ typeof(DropFilesBehavior),
+ new PropertyMetadata(false, OnAllowOpenChanged));
+
+ public static bool GetAllowOpen(DependencyObject source)
+ {
+ return (bool)source.GetValue(AllowOpenProperty);
+ }
+
+ public static void SetAllowOpen(DependencyObject source, bool value)
+ {
+ source.SetValue(AllowOpenProperty, value);
+ }
+
+ private static void OnAllowOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ UIElement uiElement = d as UIElement;
+ uiElement.Drop -= UIElement_Drop;
+
+ if ((bool)e.NewValue)
+ {
+ uiElement.Drop += UIElement_Drop;
+ }
+ }
+
+ private static void UIElement_Drop(object sender, DragEventArgs e)
+ {
+ UIElement uiElement = sender as UIElement;
+
+ // Sanity check just in case this was somehow send by something else
+ if (uiElement == null)
+ return;
+
+ if (e.Data.GetDataPresent(DataFormats.FileDrop))
+ {
+ string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];
+ Task.Run(() => OpenDocument(droppedFilePaths));
+ }
+ }
+
+ public static async Task OpenDocument(string[] droppedFilePaths)
+ {
+ var shell = IoC.Get();
+ var providers = IoC.GetAllInstances(typeof(IEditorProvider)).Cast();
+
+ foreach (var newPath in droppedFilePaths)
+ {
+ // Check if file type is supprted
+ if (providers.FirstOrDefault(p => p.Handles(newPath)) == null)
+ continue;
+
+ // Check if the document is already open
+ bool foundInShell = false;
+ foreach (var document in shell.Documents.OfType().Where(d => !d.IsNew))
+ {
+ if (string.IsNullOrEmpty(document.FilePath))
+ continue;
+
+ var docPath = Path.GetFullPath(document.FilePath);
+ if (string.Equals(newPath, docPath, System.StringComparison.OrdinalIgnoreCase))
+ {
+ shell.OpenDocument(document);
+ foundInShell = true;
+ break;
+ }
+ }
+
+ if (!foundInShell)
+ {
+ shell.OpenDocument(await OpenFileCommandHandler.GetEditor(newPath));
+
+ // Add the file to the recent documents list
+ //shell.RecentFiles.Update(newPath);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/Gemini/Modules/Shell/Views/ShellView.xaml b/src/Gemini/Modules/Shell/Views/ShellView.xaml
index d2bd5b79..77079d34 100644
--- a/src/Gemini/Modules/Shell/Views/ShellView.xaml
+++ b/src/Gemini/Modules/Shell/Views/ShellView.xaml
@@ -6,6 +6,7 @@
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:converters="clr-namespace:Gemini.Modules.Shell.Converters"
xmlns:toolbarcontrols="clr-namespace:Gemini.Modules.ToolBars.Controls"
+ xmlns:b="clr-namespace:Gemini.Modules.Shell.Behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
@@ -28,7 +29,9 @@
+ LayoutUpdated="OnManagerLayoutUpdated"
+ b:DropFilesBehavior.AllowOpen="True"
+ AllowDrop="True">