在以前的文章中,写过微软新特性Drag&Drop,当时可能由于处于Win10预览版,使用的VS也是预览版,只实现了从桌面拖拽文件到UWP App中,没能实现从UWP拖拽元素到Desktop App & UWP App中。昨天重新研究了Win10 拖拽这一块,发现以前没能实现的功能,在正式版的环境下都可以实现了,做个笔记以防日后忘记。

在UWP中,想要拖动元素到Desktop或者另一个UWP App中,除了设置元素的CanDrag="True"我们要使用元素的DragStarting事件,CanDrag属性设置元素能被拖动,DragStarting事件中我们便可以为拖动准备数据,改变拖动时的UI等一些操作。

我们依然使用上篇Drag&Drop文章中例子,在底部新增一个Img元素,设置如下:

 <Image  x:Name="img"
CanDrag="True"
Source="Assets/I Am 1%.jpg"
DragStarting="Image_DragStarting"/>

我们要用到事件的DragStartingEventArgs参数,在该参数中我们可以为拖动准备拖动的数据,更改UI设置,其中有几个重要的属性和方法:

<!--/* DragStartingEventArgs.Data中可以设置很多类型的数据:

        ·public void SetBitmap(RandomAccessStreamReference value); 设置 DataPackage 中包含的位图图像。

        ·public void SetData(System.String formatId, [HasVariant] System.Object value); 设置 RandomAccessStream 格式的 DataPackage 中包含的数据。

        ·public void SetHtmlFormat(System.String value); 向 DataPackage 添加 HTML 内容。

        ·public void SetRtf(System.String value); 设置 DataPackage 中包含 RTF 格式内容。

        ·public void SetStorageItems(IEnumerable<IStorageItem> value); 设置存储对象

        ·public void SetStorageItems(IEnumerable<IStorageItem> value, System.Boolean readOnly);设置存储对象 只读模式

        ·public void SetText(System.String value); 设置 DataPackage 包含的文本。

        ·public void SetUri(Uri value); 设置一个Uri

        ·public void SetWebLink(Uri value); 设置一个WebLink

        //设置拖动时的图标

        ·args.DragUI.SetContentFromBitmapImage     设置一个bitmap图片

        ·args.DragUI.SetContentFromDataPackage(); 设置来源于拖动的数据

        注:

        拖动源设置了相应的数据类型后,如果拖动元素到另一个UWP App中(接收者),

        则接收者需要根据相应的数据类型才能取出数据,

        如果不确定数据类型可以使用DragEventArgs参数的DataView.Contains(StandardDataFormats formats)方法来确定是否包含某种数据类型

        然后再进行取出,没有判断直接强制取出,如果类型不匹配接收者会报错

*/-->

我们在DragStarting事件中处理拖动如下:

private async void Image_DragStarting(UIElement sender, DragStartingEventArgs args)
{
//设置预览拖动时的图标 来源于数据
args.DragUI.SetContentFromDataPackage(); // 设置一个图片替换拖动时的图标
// args.DragUI.SetContentFromBitmapImage(new BitmapImage(new Uri("ms-appx:///Assets/Data-Export.png")) { DecodePixelWidth = 48, DecodePixelHeight = 48 },new Point(0,0)); // 拖动的行为,这里选择Copy 注意,如果选择 Move,拖动完成后会删除源文件
args.Data.RequestedOperation = DataPackageOperation.Copy; /* DragStartingEventArgs.Data中可以设置很多类型的数据:
·public void SetBitmap(RandomAccessStreamReference value); 设置 DataPackage 中包含的位图图像。
·public void SetData(System.String formatId, [HasVariant] System.Object value); 设置 RandomAccessStream 格式的 DataPackage 中包含的数据。
·public void SetHtmlFormat(System.String value); 向 DataPackage 添加 HTML 内容。
·public void SetRtf(System.String value); 设置 DataPackage 中包含 RTF 格式内容。
·public void SetStorageItems(IEnumerable<IStorageItem> value); 设置存储对象
·public void SetStorageItems(IEnumerable<IStorageItem> value, System.Boolean readOnly);设置存储对象 只读模式
·public void SetText(System.String value); 设置 DataPackage 包含的文本。
·public void SetUri(Uri value); 设置一个Uri
·public void SetWebLink(Uri value); 设置一个WebLink 注:
拖动源设置了相应的数据类型后,如果拖动元素到另一个UWP App中(接收者),
则接收者需要根据相应的数据类型才能取出数据,
如果不确定数据类型可以使用DragEventArgs参数的DataView.Contains(StandardDataFormats formats)方法来确定是否包含某种数据类型
然后再进行取出,没有判断直接强制取出,如果类型不匹配接收者会报错
*/ // 设置拖动data 添加一些StorageItems数据,这里取一些img图片,这些图片拖动后会copy到拖动目标上
// 如果拖动到桌面文件夹,则会copy文件到文件夹
var folder = await Package.Current.InstalledLocation.GetFolderAsync(@"Imgs");
args.Data.SetStorageItems(await folder.GetFilesAsync()); // 设置BitMap数据
var sf = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\I Am 1%.jpg");
args.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(sf));
}

上面我们一共设置两种数据,第一种是通过args.Data.SetStorageItems()方法将指定文件夹下的图片赋值到拖动Data上,第二种我们通过args.Data.SetBitmap()方法设置了一个图片到Data的BitMap中。

使用时,我们在拖动元素到另一个App(接收者)中时,就要根据上面具体设置的数据类型来获取到相应的数据。

接下来我们创建一个新的UWP App(接收者) ,界面上放置一个ListView,并设置可接受拖动数据,然后订阅相关的拖动事件如下:

 <Grid x:Name="MainGrid"
AllowDrop="True"
Drop="VcBorder_Drop"
DragOver="VcBorder_DragOver"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView Margin="8" x:Name="ImgList"/>
</Grid>

我们要实现的功能就是,从一个App中拖动元素到这个App中,拖动完成后获取拖动数据(一组图片和一个BitMap对象),获取的图片添加到ListView中,获取的BitMap对象则给Grid容器的背景色赋值。

DragOver事件中,我们可以更改拖动元素到目标范围内时的UI外观,定制如下:

 private void VcBorder_DragOver(object sender, DragEventArgs e)
{
Debug.WriteLine("[Info] DragOver");
//设置操作类型
e.AcceptedOperation = DataPackageOperation.Copy; //设置提示文字
e.DragUIOverride.Caption = "拖放此处即可添加文件 o(^▽^)o";
}

Drop事件中我们来处理拖动完成时的逻辑,如下:

 private async void VcBorder_Drop(object sender, DragEventArgs e)
{
/*
接收端可以根据e.DataView.Contains(StandardDataFormats formats) 来确定拖动过来的数据中是否包含某种数据类型
如果数据类型不匹配就取的话则会报错
*/
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
//获取存储对象
var items = await e.DataView.GetStorageItemsAsync(); //咨询是否接受文件
var dialog = new ContentDialog
{
Title = "提示",
Content = new TextBlock {Text = $"从其他App中拖动来{items.Count}个文件,是否接受?"},
IsPrimaryButtonEnabled = true,
IsSecondaryButtonEnabled = true,
PrimaryButtonText = "Ok",
SecondaryButtonText = "Cancel"
};
dialog.PrimaryButtonClick += async (s, a) =>
{
//开始接受文件 并添加到ImgList中 ,或者也可以做其他操作,例如保存文件到App中
//过滤下文件,只取jpg文件
foreach (var item in items.OfType<StorageFile>()
.Where(i => i.FileType.Equals(".jpg")).ToList())
{
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(await item.OpenAsync(FileAccessMode.Read));
ImgList.Items?.Add(new Image {Source = bitmapImage});
}
};
dialog.SecondaryButtonClick += (s, a) => { dialog.Hide(); };
await dialog.ShowAsync();
} if (e.DataView.Contains(StandardDataFormats.Bitmap))
{
//获取bitmap对象
var items = await e.DataView.GetBitmapAsync();
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(await items.OpenReadAsync());
//设置MainGrid背景图片
MainGrid.Background = new ImageBrush {ImageSource = bitmap};
}
}

有关更多Drop事件&DragOver事件详细设置请参与文章:UWP/Win10新特性系列—Drag&Drop拖动打开文件

这样我们就实现了从一个UWP中拖动元素到其他App中,例如可以拖动到文件夹中快速保存图片,也可以拖动到outlook中快速插入附件,也可以拖动图片到另一个App中进行操作等。

效果图:

推荐一个UWP开发群:53078485 大家可以进来一起学习

最新文章

  1. JQuery Mobile 页面参数传递
  2. JS如何实现点击页面内任意的链接均加参数跳转?
  3. Using OpenCV with gcc and CMake
  4. hdu 4619 二分图最大匹配 ——最大独立集
  5. 用JS实现发邮件的功能 完美解决
  6. ssh无法远程登陆别的机器
  7. shell 处理小数位加减法(比较)运算
  8. 数据库和Content Provider
  9. MySQL ProxySQL相关维护说明
  10. python之路-bytes数据类型
  11. 06-搭建master集群
  12. BZOJ1280 Emmy卖猪pigs 网络流
  13. shiro中编码/加密
  14. yii2 查询数据库语法
  15. (十三)Jmeter之Bean Shell 的使用(二)
  16. Extjs window组件 拖动统制
  17. SuperWebSocket
  18. 64位机的pl/sql不安装32位oracle的连接方式
  19. 动态设置spring配置PropertyPlaceholderConfigurer location的路径
  20. 基于Xtrabackup备份集来恢复某个误删除的表(drop)

热门文章

  1. 楼盘信息sq
  2. protocol buffer c++ python库安装
  3. lamp遇到问题
  4. 虚拟化 模板制作 rhev笔记
  5. PHPCMS开启伪静态和织梦开启伪静态的优缺点比较
  6. typeof(self) 的作用
  7. 1476. Lunar Code
  8. ScrollView can host only one direct child
  9. Java系列笔记(2) - Java RTTI和反射机制
  10. jdbc链接mysql插入数据后显示问号