UWP/Win10新特性系列—Drag&Drop 拖動打開文件

   

  在Win10 App開發中,微軟新增了系統PC文件與UWP 之間的文件拖拽行爲,它支持將系統磁盤上的文件以拖拽的形式拖入App中並處理,在前不久的微軟build 2015開發者大會上微軟展現的UWP版微信的拖拽文件就是使用的這個功能,接下來,咱們一塊兒看看該功能是怎麼實現的。數組

 

    首先咱們要介紹的是DragEventArgs這個類,是在拖拽中爲咱們提供數據和UI樣式定製的,在拖拽事件中,事件參數對象就是該類型,這個類在Win10中增長了一個新的接口的繼承->IDragEventArgs2接口,該接口中提供以下新的成員屬性:微信

1 internal interface IDragEventArgs2
2  {
3      DataPackageOperation AcceptedOperation { get; set; }
4      DataPackageView DataView { get; }
5      DragUIOverride DragUIOverride { get; }
6      DragDropModifiers Modifiers { get; }
7  
8      DragOperationDeferral GetDeferral();
9  }

其中有三個比較重要的:app

  • AcceptedOperation:這個是獲取或設置指定拖動事件發起方可執行哪些操做,值是DataPackageOperation枚舉類型。能夠制定四種操做類型(None,Move,Copy,Link),指定不一樣類型時在拖拽時會產生不一樣的圖標樣式。
  • DataPackageView:這個屬性是用來獲取拖拽進來的對象的數據的,根據它能夠拿到拖拽對象。
  • DragUIOverride:這個是用來自定義拖拽時的UI外觀的,能夠改變拖拽時的圖標、提示語、是否顯示圖標和提示語等。

要想讓元素接受拖拽對象到它本身自己,咱們要設置元素的AllowDrop屬性爲True,拖拽會觸發四種事件:DragEnter(進入接受拖拽的範圍)、DragOver(處於接受拖拽範圍)、Drop(鬆開鼠標)、DragLeave(離開接受拖拽的範圍),總體的拖拽流程是這樣的:dom

而咱們須要訂閱該元素的Drop、DragOver兩個事件,DragOver事件會在拖拽對象到該元素時一直被觸發,而當鼠標鬆開拖拽時會觸發Drop事件。async

接下來,咱們演示下從系統磁盤文件夾拖拽一些vcf聯繫人到咱們的App中。ide

界面上放置三個區域:接受拖拽區、文件顯示區、拖拽刪除區學習

 1 <Grid  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
 2       <Grid.RowDefinitions>
 3           <RowDefinition Height="*"/>
 4           <RowDefinition Height="8*"/>
 5           <RowDefinition Height="*"/>
 6       </Grid.RowDefinitions>
 7  
 8       <!--接受拖拽的區域 Start-->
 9       <Border AllowDrop="True"
10               Drop="VcBorder_Drop"
11               DragOver="VcBorder_DragOver"
12               Background="{ThemeResource ToolTipForegroundThemeBrush}" >
13           <TextBlock Text="請嘗試拖動vcf名片到這裏" RequestedTheme="Dark" HorizontalAlignment="Center" VerticalAlignment="Center"  />
14       </Border>
15       <!--接受拖拽的區域 End-->
16  
17       <!--拖拽過來的文件顯示區 Start-->
18       <Grid Grid.Row="1" >
19           <ListView x:Name="VcList" CanDragItems="True"  DragItemsStarting="VcList_DragItemsStarting"
20                     ItemsSource="{x:Bind VCards }" >
21               <ListView.ItemTemplate>
22                   <DataTemplate x:DataType="local:LinkManModel">
23                       <Grid Margin="0,8">
24                           <Grid.ColumnDefinitions>
25                               <ColumnDefinition Width="2*"/>
26                               <ColumnDefinition Width="3*"/>
27                           </Grid.ColumnDefinitions>
28                           <Grid>
29                               <Image Source="Assets/I Am 1%.jpg"  />
30                               <Image Source="{x:Bind Img}"  />
31                           </Grid>
32                           <Grid Margin="12,0" Grid.Column="1">
33                               <Grid.RowDefinitions>
34                                   <RowDefinition Height="*"/>
35                                   <RowDefinition Height="*"/>
36                                   <RowDefinition Height="*"/>
37                               </Grid.RowDefinitions>
38                               <TextBlock>
39                                     <Run Text="姓名:"/>
40                                     <Run Text="{x:Bind Name}"/>
41                               </TextBlock>
42                               <TextBlock Grid.Row="1">
43                                     <Run Text="Phone:"/>
44                                     <Run Text="{x:Bind Phone}"/>
45                               </TextBlock>
46                               <TextBlock Grid.Row="2">
47                                    <Run Text="Email:"/>
48                                    <Run Text="{x:Bind Email}"/>
49                               </TextBlock>
50                           </Grid>
51                       </Grid>
52                   </DataTemplate>
53               </ListView.ItemTemplate>
54           </ListView>
55       </Grid>
56       <!--拖拽過來的文件顯示區 End-->
57  
58       <!--拖拽刪除區 Start-->
59       <Border Grid.Row="2" x:Name="DelBorder"
60           AllowDrop="True"
61               Drop="DelBorder_Drop"
62               DragOver="DelBorder_DragOver"
63               Background="{ThemeResource ToolTipForegroundThemeBrush}">
64           <TextBlock Text="請拖動名片到這裏來刪除" RequestedTheme="Dark" HorizontalAlignment="Center" VerticalAlignment="Center"  />
65       </Border>
66       <!--拖拽刪除區 End-->
67   </Grid>

後臺代碼:ui

  1 public sealed partial class MainPage : Page
  2 {
  3  
  4     public ObservableCollection<LinkManModel> VCards = new ObservableCollection<LinkManModel>();
  5  
  6     public MainPage()
  7     {
  8         this.InitializeComponent();
  9     }
 10  
 11     /// <summary>
 12     /// 拖拽完成
 13     /// </summary>
 14     private async void VcBorder_Drop(object sender, DragEventArgs e)
 15     {
 16         Debug.WriteLine("[Info] Drop");
 17  
 18         if (e.DataView.Contains(StandardDataFormats.StorageItems))
 19         {
 20             Debug.WriteLine("[Info] DataView Contains StorageItems");
 21             var items = await e.DataView.GetStorageItemsAsync();
 22  
 23             //文件過濾 只取vcf文件 PS:若是拖過來的是文件夾 則須要對文件夾處理 取出文件夾文件
 24             items = items.OfType<StorageFile>()
 25                 .Where(s => s.FileType.Equals(".vcf")).ToList() as IReadOnlyList<IStorageItem>;
 26             if (items != null && items.Any())
 27             {
 28                 //添加VCard
 29                 await AddVCard(items);
 30             }
 31         }
 32     }
 33  
 34     /// <summary>
 35     /// 添加VCard
 36     /// </summary>
 37     /// <param name="items"></param>
 38     /// <returns></returns>
 39     private async Task AddVCard(IReadOnlyList<IStorageItem> items)
 40     {
 41         foreach (var item in items)
 42         {
 43             #region 圖片的處理
 44             //var storageFile = item as StorageFile;
 45             //var bitmapImage = new BitmapImage();
 46             //await bitmapImage.SetSourceAsync(await storageFile.OpenAsync(FileAccessMode.Read));
 47             #endregion
 48  
 49             var linkMan = new LinkManModel();
 50             var storageFile = item as StorageFile;
 51             var stream = await storageFile.OpenStreamForReadAsync();
 52             using (StreamReader reader = new StreamReader(stream))
 53             {
 54                 var str = reader.ReadToEnd();
 55                 var vcard = VCard.Parse(str);
 56                 var info = vcard.Properties;
 57                 linkMan.Name = info.FirstOrDefault(s => s.Name == "FN") == null ? null : info.FirstOrDefault(s => s.Name == "FN").EncodedValue;
 58                 linkMan.Phone = info.FirstOrDefault(s => s.Name == "TEL") == null ? null : info.FirstOrDefault(s => s.Name == "TEL").EncodedValue;
 59                 linkMan.Email = info.FirstOrDefault(s => s.Name == "EMAIL") == null ? null : info.FirstOrDefault(s => s.Name == "EMAIL").EncodedValue;
 60                 var photoStr = info.FirstOrDefault(s => s.Name == "PHOTO") == null ? null : info.FirstOrDefault(s => s.Name == "PHOTO").EncodedValue;
 61                 if (photoStr != null)
 62                     linkMan.Img = await convertToImage(photoStr);
 63  
 64             }
 65             if (linkMan != null)
 66             {
 67                 VCards.Add(linkMan);
 68             }
 69         }
 70     }
 71  
 72     /// <summary>
 73     /// base64 To BitmapImage
 74     /// </summary>
 75     private async static Task<BitmapImage> convertToImage(string strimage)
 76     {
 77         try
 78         {
 79             byte[] bitmapArray;
 80             bitmapArray = Convert.FromBase64String(strimage);
 81             MemoryStream ms = new MemoryStream(bitmapArray);
 82             InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
 83             //將randomAccessStream 轉成 IOutputStream
 84             var outputstream = randomAccessStream.GetOutputStreamAt(0);
 85             //實例化一個DataWriter
 86             DataWriter datawriter = new DataWriter(outputstream);
 87             //將Byte數組數據寫進OutputStream
 88             datawriter.WriteBytes(bitmapArray);
 89             //在緩衝區提交數據到一個存儲區
 90             await datawriter.StoreAsync();
 91  
 92             //將InMemoryRandomAccessStream給位圖
 93             BitmapImage bitmapImage = new BitmapImage();
 94             bitmapImage.SetSource(randomAccessStream);
 95  
 96             return bitmapImage;
 97         }
 98         catch
 99         {
100             return null;
101         }
102     }
103  
104     /// <summary>
105     /// 進入到接受拖拽區
106     /// </summary>
107     private void VcBorder_DragOver(object sender, DragEventArgs e)
108     {
109         Debug.WriteLine("[Info] DragOver");
110         //設置操做類型
111         e.AcceptedOperation = DataPackageOperation.Copy;
112  
113         //設置提示文字
114         e.DragUIOverride.Caption = "拖放此處便可添加文件 o(^▽^)o";
115  
116         ////是否顯示拖放時的文字 默認爲true
117         //e.DragUIOverride.IsCaptionVisible = true;
118  
119         ////是否顯示文件圖標,默認爲true
120         //e.DragUIOverride.IsContentVisible = true;
121  
122         ////Caption 前面的圖標是否顯示。默認爲 true
123         //e.DragUIOverride.IsGlyphVisible = true;
124  
125         ////自定義文件圖標,能夠設置一個圖標
126         //e.DragUIOverride.SetContentFromBitmapImage(new BitmapImage(new Uri("ms-appx:///Assets/copy.jpg")));
127     }
128  
129     /// <summary>
130     /// 要刪除的項
131     /// </summary>
132     LinkManModel DelItem;
133  
134     /// <summary>
135     /// 開始拖拽Item 以準備刪除
136     /// </summary>
137     private void VcList_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
138     {
139         DelItem = e.Items.FirstOrDefault() as LinkManModel;
140     }
141  
142     /// <summary>
143     /// 拖拽刪除完成
144     /// </summary>
145     private void DelBorder_Drop(object sender, DragEventArgs e)
146     {
147         VCards.Remove(DelItem);
148     }
149  
150     /// <summary>
151     /// 進入拖拽刪除區
152     /// </summary>
153     private void DelBorder_DragOver(object sender, DragEventArgs e)
154     {
155         //設置操做類型
156         e.AcceptedOperation = DataPackageOperation.Move;
157         e.DragUIOverride.Caption = "刪除";
158         e.DragUIOverride.IsContentVisible = false;
159     }
160      
161 }
162  
163 public class LinkManModel
164 {
165     public string Name { get; set; }
166  
167     public string Email { get; set; }
168  
169     private string _Phone;
170     public string Phone { get { return string.IsNullOrEmpty(_Phone)? null : Regex.Replace(_Phone, @"(?im)(\d{3})(\d{4})(\d{4})", "$1***$3"); } set { _Phone = value; } }
171     public BitmapImage Img { get; set; }
172 }

效果:this

 

推薦一個UWP開發羣:53078485 你們能夠進來一塊兒學習spa

相關文章
相關標籤/搜索