1、Copy and paste text:
本例介绍使用系统的粘贴板,复制和粘贴不同格式的文本,比如普通的 字符串或者 html 字符串。复制时,
需要把 文本进行格式化后放入 DataPackage 中。然后把 DataPackage 放入 粘贴板中。粘贴时,从粘贴板中
获取 DataPackgeView ,并且从中按照 所希望的格式从中获取内容。如果需要处理文本中包含的应用本地的图片资源
的引用时,需要使用 ResourceMap 集合(例如在本例中使用的 字符串:<img id=\"scenario1LocalImage\" src=\"" + imgSrc + "\" /> )。
DataPackage 类同样可以用来去 分享、发布程序中的内容。
程序运行显示:
放入粘贴板中的源截图:
读取粘贴板中的资源并显示截图:
xaml 页面中的控件资源:
//显示放入到粘贴板中的 html 文本字符串 <WebView x:Name="Description" Height="210" Width="550" HorizontalAlignment="Left"/> //“复制”命令 按钮 <Button x:Name="CopyButton" Content="Copy text above" Margin="0,0,10,0"/> //“粘贴”命令 按钮 <Button x:Name="PasteButton" Content="Paste text from clipboard" Margin="0,0,10,0"/> //显示从 粘贴板中的获取的 文本字符串(去除其中的 html 标签,只提取文本) <TextBlock x:Name ="OutputText" TextWrapping="Wrap" Text="" /> //显示放入 DataPackage 对象中的 ResourceMap 中的资源的 //键 (如本例的:dataPackage.ResourceMap[imgSrc] 中的键 imgSrc) <TextBlock x:Name ="OutputResourceMapKeys" Style="{StaticResource BasicTextStyle}"
TextWrapping="Wrap" Text="" /> //显示 html 格式的文本 <WebView x:Name="OutputHtml" HorizontalAlignment="Left" Height="160" Width="800" />
页面相应的 C# 代码:
字符串变量:
#region private member variables //在 webview 中显示的 html 源 private string htmlFragment = "Use clipboard to copy and paste text in different formats, including plain text, and formatted text (HTML). <br />" + " To <b>copy</b>, add text formats to a <i>DataPackage</i>, and then place <i>DataPackage</i> to Clipboard.<br /> " + "To <b>paste</b>, get <i>DataPackageView</i> from clipboard, and retrieve the content of the desired text format from it.<br />" + "To handle local image files in the formatted text (such as the one below), use ResourceMap collection." + "<br /><img id=\"scenario1LocalImage\" src=\"" + imgSrc + "\" /><br />" + "<i>DataPackage</i> class is also used to share or send content between applications. <br />" + "See the Share SDK sample for more information."; //引用到本程序中的图片 private const string imgSrc = "ms-appx-web:///assets/windows-sdk.png"; #endregion
// 把内容放入 粘贴板
void CopyButton_Click(object sender, RoutedEventArgs e) { // 把内容安装 html 的格式放入到 DataPage 中 // HtmlFormatHelper.CreateHtmlFormat() : 采用表示 HTML 内容 //的字符串并添加必要的标头以确保共享和剪贴板操作的格式正确无误。 string htmlFormat = HtmlFormatHelper.CreateHtmlFormat(this.htmlFragment); //DataPackage : 包含用户希望与另一个应用程序交换的数据。 var dataPackage = new DataPackage(); dataPackage.SetHtmlFormat(htmlFormat); //把内容作为普通文本放入到 Datapackage 中 string plainText = HtmlUtilities.ConvertToText(this.htmlFragment); //设置 DataPackage 包含的文本。 dataPackage.SetText(plainText); // resourceMap填充与StreamReference对象对应于本地的图像文件嵌入到HTMLML var imgUri = new Uri(imgSrc); var imgRef = RandomAccessStreamReference.CreateFromUri(imgUri); dataPackage.ResourceMap[imgSrc] = imgRef; try { // 把本 DataPackage 对象放入到粘贴板中 Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); OutputText.Text = "Text and HTML formats have been copied to clipboard. "; } catch (Exception ex) { //操作失败,例如其它应用程序正在打开着粘贴板 } }
//从粘贴板中获取内容:
async void PasteButton_Click(object sender, RoutedEventArgs e) { //获取剪贴板对象中存储的当前内容。 DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.Text)) { try { //获取 DataPackageView 对象中的文本。 var text = await dataPackageView.GetTextAsync(); OutputText.Text = "Text: " + Environment.NewLine + text; } catch (Exception ex) { //fail } } else { // fail : Text format is not available in clipboard"; } if (dataPackageView.Contains(StandardDataFormats.Html)) { this.DisplayResourceMapAsync(dataPackageView); string htmlFormat = null; try { // 获取 DataPackageView 对象中存储的 HTML。 htmlFormat = await dataPackageView.GetHtmlFormatAsync(); } catch (Exception ex) { //fail : "Error retrieving HTML format from Clipboard "; } if (htmlFormat != null) { //获取代表 HTML 片段的字符串 。 string htmlFragment = HtmlFormatHelper.GetStaticFragment(htmlFormat); OutputHtml.NavigateToString("HTML:<br/ > " + htmlFragment); } } else { OutputHtml.NavigateToString("HTML:<br/ > HTML format is not available in clipboard"); } }
//上面调用的 this.DisplayResourceMapAsync(dataPackageView) 方法:
//本例没有解析放入 resource map 中的资源。请参阅剪贴板的示例 //JavaScript范例如何使用资源映射对本地的图像显示为一个HTML格 //式。这个示例只会演示如何得到一个资源映射对象并提取其键值async void DisplayResourceMapAsync(DataPackageView dataPackageView) { OutputResourceMapKeys.Text = Environment.NewLine + "Resource map: "; IReadOnlyDictionary<string, RandomAccessStreamReference> resMap = null; try { //获取 HTML 内容中引用的数据(如图像)。 resMap = await dataPackageView.GetResourceMapAsync(); } catch (Exception ex) { //从粘贴板中获取 Resource map 失败 } if (resMap != null) { if (resMap.Count > 0) { //显示 Resource map 中的键 foreach (var item in resMap) { OutputResourceMapKeys.Text += Environment.NewLine + "Key: " + item.Key; } } else { // Resource map 是空的; } } }
2、Copy and paste an image :
这个 DataPackage 对象也可以保存 bitmap 对象。本示例演示使用 picker 选择图片文件,并把它
复制到粘贴板中,然后把它粘贴到应用程序中。图像也可以通过提供延迟渲染,当直到目标应用程序请求它时,
源应用才提供数据。
效果截图:
三个命令按钮:
粘贴图片结果:
页面的 xaml 代码:
//拷贝图片 <Button x:Name="CopyButton" Content="Select image and copy" Margin="0,0,10,0" Click="CopyButton_Click"/> //拷贝图片。当目标程序需要时,才复制源图片 <Button x:Name="CopyWithDelayRenderingButton" Content="Select image and copy using delayed rendering" Margin="0,0,10,0" Click="CopyWithDelayRenderingButton_Click"/> //显示图片 <Button x:Name="PasteButton" Content="Paste" Margin="0,0,10,0" Click="PasteButton_Click"/> <Image x:Name="ImageHolder" HorizontalAlignment="Left" Visibility="Collapsed" MaxHeight="300" MaxWidth="400"/>
对应的 C# 源码:
void CopyButton_Click(object sender, RoutedEventArgs e) { this.CopyBitmap(false); } void CopyWithDelayRenderingButton_Click(object sender, RoutedEventArgs e) { this.CopyBitmap(true); } async private void CopyBitmap(bool isDelayRendered) { if (rootPage.EnsureUnsnapped()) { var imagePicker = new FileOpenPicker { ViewMode = PickerViewMode.Thumbnail, // 缩略图象集。 SuggestedStartLocation = PickerLocationId.PicturesLibrary, FileTypeFilter = { ".jpg", ".png", ".bmp", ".gif", ".tif" } }; var imageFile = await imagePicker.PickSingleFileAsync(); if (imageFile != null) { var dataPackage = new DataPackage(); // 是否延迟把选择的图片放入到粘贴板中 if (isDelayRendered) { //设置委托以处理来自目标应用程序的请求。 dataPackage.SetDataProvider(StandardDataFormats.Bitmap,
request => OnDeferredImageRequestedHandler(request, imageFile)); OutputText.Text = "Image has been copied using delayed rendering"; } else { // 设置 DataPackage 中包含的位图图像。 dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageFile)); OutputText.Text = "Image has been copied"; } try { // 设置剪贴板对象中存储的当前内容。 Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); } catch (Exception ex) { // 把数据复制到粘贴板中操作失败,可能其他应用正在占用粘贴板 } } else { // 没有选择图片 } } } //当有粘贴请求时触发 async private void OnDeferredImageRequestedHandler(DataProviderRequest request, StorageFile imageFile) { if (imageFile != null) { //可让应用程序延迟共享的对象。 var deferral = request.GetDeferral(); // Surround try catch to ensure that we always call Complete on defferal. try { using (var imageStream = await imageFile.OpenAsync(FileAccessMode.Read)) { // 异步创建新的 BitmapDecoder 并使用流将其初始化。 var imageDecoder = await BitmapDecoder.CreateAsync(imageStream); // Re-encode the image at 50% width and height var inMemoryStream = new InMemoryRandomAccessStream(); var imageEncoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryStream, imageDecoder); imageEncoder.BitmapTransform.ScaledWidth = (uint)(imageDecoder.OrientedPixelWidth * 0.5); imageEncoder.BitmapTransform.ScaledHeight = (uint)(imageDecoder.OrientedPixelHeight * 0.5); await imageEncoder.FlushAsync(); request.SetData(RandomAccessStreamReference.CreateFromStream(inMemoryStream)); } } finally { // 通知目标应用程序 DataPackage 已准备好进行处理。 deferral.Complete(); } } }
3、Copy and paste files :
这个 DataPackage 也能处理文件。使用 picker 选择文件,把它们复制到粘贴板中,然后粘贴这些文件。
本示例是把它们拷贝到本应用的本地 state 文件夹中。
xaml 页面放两个按钮:
xaml 代码:
//选择并复制 <Button x:Name="CopyButton" Content="Select file and copy" Margin="0,0,10,0" Click="CopyButton_Click"/> //粘贴 <Button x:Name="PasteButton" Content="Paste" Margin="0,0,10,0" Click="PasteButton_Click"/>
相应的 C# 源码:
//复制
async void CopyButton_Click(object sender, RoutedEventArgs e) { var filePicker = new FileOpenPicker { ViewMode = PickerViewMode.List, FileTypeFilter = { "*" } }; // 显示文件选取器,以便用户可以选择多个文件。 var storageItems = await filePicker.PickMultipleFilesAsync(); if (storageItems.Count > 0) { OutputText.Text += storageItems.Count + " file(s) are copied into clipboard"; var dataPackage = new DataPackage(); dataPackage.SetStorageItems(storageItems); // 源应用程序的操作请求。 将内容复制到目的地。 dataPackage.RequestedOperation = DataPackageOperation.Copy; try { Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); } catch (Exception ex) { // 把数据复制到粘贴板中操作失败,可能其他应用正在占用粘贴板 } } else { //没有选择文件 } }
//粘贴
async void PasteButton_Click(object sender, RoutedEventArgs e) { // 从粘贴板中获取 DataPackageView 对象 var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.StorageItems)) { IReadOnlyList<IStorageItem> storageItems = null; try { storageItems = await dataPackageView.GetStorageItemsAsync(); } catch (Exception ex) { // 没有数据 } if (storageItems != null) { // 粘贴板中 文件的数量 : storageItems.Count // 获取本地应用程序数据存储区中的根文件夹 : ApplicationData.Current.LocalFolder.Path // 获取请求的操作(例如复制或移动)。主要用于“剪贴板”操作。 var operation = dataPackageView.RequestedOperation; //"Requested Operation "; switch (operation) { case DataPackageOperation.Copy: break; case DataPackageOperation.Link: break; case DataPackageOperation.Move: break; case DataPackageOperation.None: break; default: break; } foreach (var storageItem in storageItems) { var file = storageItem as StorageFile; if (file != null) { // 把文件复制到本地应用程序的路径下 var newFile = await file.CopyAsync(ApplicationData.Current.LocalFolder, file.Name,
NameCollisionOption.ReplaceExisting); } else { var folder = storageItem as StorageFolder; if (folder != null) { // 如果是一个文件夹而不是一个文件,则跳过 // folder.Path is a folder, skipping } } } } } else { //粘贴板中的 StorageItems 格式不可用 } }
4、Other Clipboard operations