Win10/UWP新特性—Drag&Drop 拖出元素到其他App
在以前的文章中,写过微软新特性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 大家可以进来一起学习
Win10/UWP新特性—Drag&Drop 拖出元素到其他App的更多相关文章
- Win10/UWP新特性—SharedStorageAccessManager 共享文件
首先先给大家推荐一个UWP/Win10开发者群:53078485 里面有很多大婶,还有很多学习资源,欢迎大家来一起讨论Win10开发! 在UWP开发中,微软提供了一个新的特性叫做SharedStor ...
- Win10/UWP新特性系列—Launcher实现应用间的通信
UWP中,微软为Windows.System.Launcher启动器新增了很多的功能,以前只能启动App,打开指定扩展名文件,对uri协议的解析,以及当启动的应用没有安装时则会提示前往商店下载等. 如 ...
- Win10/UWP新特性系列—电池报告
UWP中,新增了当节电模式开启时,App能获取到通知的API,通过响应电源条件的更改,比如咨询用户是否使用黑色背景等来帮助延长电池使用时间. 通过Windows.Devices.Power命名空间中的 ...
- Win10/UWP新特性系列-GetPublisherCacheFolder
微软Windows Runtime App拥有很强的安全模型来防止不同App之间的数据获取和共享,也就是我们所说的"沙盒机制",每个App都运行在Windows沙盒中,App之间的 ...
- 【转】Win10/UWP新特性系列—Web
Internet Explorer Internet Explorer 在Windows 10 升级为Edge模式,是一种交互性和兼容性都很强的新型浏览器,该浏览器相比以前的版本更新了超过2000个操 ...
- Win10/UWP新特性系列—使用打印机
微软在Win10时代终于完成的设备系统的大统一,"56个民族,56支花……"(⊙o⊙)…,既然统一了,那么也就意味着API也统一了,所以在UWP中,我们就可以使用统一的打印API来 ...
- Atitit。D&D drag&drop拖拽功能c#.net java swing的对比与实现总结
Atitit.D&D drag&drop拖拽功能c#.net java swing的对比与实现总结 1. 实现一个D&D操作一般包括三个步骤: 1 2. .net黑头的拖曳机制 ...
- atitit。win7 win8 win9 win10 win11 新特性总结与战略规划
atitit.win7 win8 win9 win10 win11 新特性总结与战略规划 1. win7 1 1.1. 发布时间 2009年10月22日 1 1.2. 稳定性大幅提升,很少蓝屏死机 ...
- atitit.D&D drag&drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结
atitit.D&D drag&drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结 1. DND的操作流程 1 2. Html5 注 ...
随机推荐
- js的规范写法ES5(自己以后按照这样写)
1.引号的使用,单引号' ' 优先(如果不是引号嵌套,不要使用双引号) 正常情况:console.log('hello there') 双引号转码: $("<div cl ...
- MYSQL5.7版本sql_mode=only_full_group_by问题
具体出错提示: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggr ...
- Hammer.js
一.前言 移动端框架当前还处在初级阶段,但相对于移动端的应用来说已经有很长时间了.虽然暂时还没有PC端开发的需求量大,但移动端的Web必然是一种趋势,在接触移动端脚本的过程中,最开始想到的是juqer ...
- MD5加密代码
import java.security.MessageDigest;public class MD5_tes { public final static String MD5(String s){ ...
- Python之路,Day7 - 面向对象编程进阶
本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 经典类vs新式类 把下面代 ...
- Redis设计与实现(一~五整合版)【搬运】
Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...
- Spring框架学习路线和概述
Spring的Ioc Spring的AOP , AspectJ Spring的事务管理 , 三大框架的整合. Spring框架的概述: 1. 什么是Spring Spring是分层的JavaSE/EE ...
- UVA 11297 线段树套线段树(二维线段树)
题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ...
- java web学习之表单
前台页面与后台页面的数据又form表单完成. <form name ="form1" method="post" action="index ...
- RASPBERRY PI wifi配置
Raspberry Pi 手把手教你在树莓派上安装USB无线网卡支持WIFI 树莓派虽然已经有了有线网卡,但是并未配置无线网卡,移动性不够强,好在机器配备了2个USB口,当然要分一个出来给WIFI无线 ...