Skip to content

Instantly share code, notes, and snippets.

@ScottIsAFool
Last active August 29, 2016 14:32
Show Gist options
  • Save ScottIsAFool/e29ae94a1589fac0702f02dcf838ec86 to your computer and use it in GitHub Desktop.
Save ScottIsAFool/e29ae94a1589fac0702f02dcf838ec86 to your computer and use it in GitHub Desktop.
DropFileBehaviour and its usage
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
using Windows.UI.Xaml;
using ScottIsAFool.Model;
using Microsoft.Xaml.Interactivity;
namespace ScottIsAFool.Behaviours
{
public class DropFileBehaviour : Behavior<UIElement>
{
private string[] _fileTypes = null; //{ ".jpg", ".jpeg", ".png", ".cr2" };
public static readonly DependencyProperty SupportedFileTypesProperty = DependencyProperty.Register(
nameof(SupportedFileTypes), typeof(string), typeof(DropFileBehaviour), new PropertyMetadata(default(string), OnSupportedFileTypesChanged));
public string SupportedFileTypes
{
get { return (string) GetValue(SupportedFileTypesProperty); }
set { SetValue(SupportedFileTypesProperty, value); }
}
public static readonly DependencyProperty DroppedCommandProperty = DependencyProperty.Register(
nameof(DroppedCommand), typeof(ICommand), typeof(DropFileBehaviour), new PropertyMetadata(default(ICommand)));
public ICommand DroppedCommand
{
get { return (ICommand) GetValue(DroppedCommandProperty); }
set { SetValue(DroppedCommandProperty, value); }
}
public static readonly DependencyProperty IsDroppingProperty = DependencyProperty.Register(
nameof(IsDropping), typeof(bool), typeof(DropFileBehaviour), new PropertyMetadata(default(bool)));
public bool IsDropping
{
get { return (bool) GetValue(IsDroppingProperty); }
set { SetValue(IsDroppingProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.AllowDrop = true;
UnregisterEvents();
AssociatedObject.Drop += AssociatedObjectOnDrop;
AssociatedObject.DragEnter += AssociatedObjectOnDragEnter;
AssociatedObject.DragLeave += AssociatedObjectOnDragLeave;
}
private void UnregisterEvents()
{
AssociatedObject.Drop -= AssociatedObjectOnDrop;
AssociatedObject.DragEnter -= AssociatedObjectOnDragEnter;
AssociatedObject.DragLeave -= AssociatedObjectOnDragLeave;
}
private void AssociatedObjectOnDragLeave(object sender, DragEventArgs dragEventArgs)
{
IsDropping = false;
}
protected override void OnDetaching()
{
base.OnDetaching();
UnregisterEvents();
}
private static void OnSupportedFileTypesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
(sender as DropFileBehaviour)?.SetFileTypes();
}
private void AssociatedObjectOnDragEnter(object sender, DragEventArgs e)
{
IsDropping = true;
e.AcceptedOperation = DataPackageOperation.Copy | DataPackageOperation.Move;
}
private void SetFileTypes()
{
var fileTypes = SupportedFileTypes?.Split(',');
_fileTypes = fileTypes;
}
private async void AssociatedObjectOnDrop(object sender, DragEventArgs e)
{
var files = await e.DataView.GetStorageItemsAsync();
var tasks = files.Cast<StorageFile>().Select(GetFileInfo);
var images = await Task.WhenAll(tasks);
var noNullImages = images.Where(x => x != null).ToList();
DroppedCommand?.Execute(noNullImages);
IsDropping = false;
}
private async Task<DroppedFile> GetFileInfo(StorageFile file)
{
try
{
if (_fileTypes == null || _fileTypes.Contains(file.FileType))
{
var stream = await file.OpenAsync(FileAccessMode.Read);
return new DroppedFile(stream, file.Name, file.FileType);
}
}
catch (Exception)
{
// ignored
}
return null;
}
}
}
using Windows.Storage.Streams;
namespace ScottIsAFool.Model
{
public class File
{
public File(IRandomAccessStream fileStream, string fileName, string fileType)
{
FileStream = fileStream;
FileName = fileName;
FileType = fileType;
}
public IRandomAccessStream FileStream { get; set; }
public string FileName { get; set; }
public string FileType { get; set; }
}
}
<Page.Resources>
<converters:BooleanToBrushConverter x:Key="DroppingColourConverter"
TrueValue="DeepSkyBlue"
FalseValue="LightGray"/>
</Page.Resources>
<Grid x:Name="RootGrid"
BorderBrush="{x:Bind DropBehaviour.IsDropping, Mode=OneWay, Converter={StaticResource DroppingColourConverter}}"
BorderThickness="2"
Margin="15">
<interactivity:Interaction.Behaviors>
<behaviours:DropFileBehaviour DroppedCommand="{x:Bind Upload.DroppedFilesCommand}"
x:Name="DropBehaviour"/>
</interactivity:Interaction.Behaviors>
</Grid>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment