图解使用Win8Api进行Metro风格的程序开发八----剪贴板
我们紧接着上篇,这篇将介绍如何使用Windows.ApplicationModel.DataTransfer API
中的DataPackage类和Clipboard类
-----------------------------------我是华丽的分割线-----------------------------------------
我们紧接着上篇,这篇将介绍如何使用Windows.ApplicationModel.DataTransfer API
中的DataPackage类和Clipboard类,来实现 复制,粘贴,剪切和移动功能。
本篇将介绍如下四个方面:
a)如何复制和粘贴文本
b)如何复制和粘贴图像
c)如何复制和粘贴文件
d)获得剪贴板的格式
e)监视剪贴板的变化
我们的创建的步骤如下:
1)为了组织文件方便,我们先建一个文件夹Clipboard
2)向文件夹中添加如下四个文件:
CopyAndPasteText.xaml,CopyAndPasteImage.xaml,
CopyAndPasteFile.xaml,OtherClipboardOperation.xaml
创建方法请参照前一篇.
3)此时的解决方案结构如下:
4)向我们的DataSource添加导航所需要的信息
修改我们的SampleDataSource.cs文件中的SampleDataSource类中的代码,
代码如下:
public SampleDataSource() { #region Group1 var group1 = new SampleDataGroup("FilePicker", "Use Windows.Storage.Pickers API", "Access and save files using the file picker", "Assets/FilePicker.jpg", ""); group1.Items.Add(new SampleDataItem("FilePicker-PickASinglePhoto", "Pick a single photo", "only one file can selected,file type is jpg,jpeg,png", "Assets/FilePicker.jpg", "only one file can selected ", "", group1, typeof(PickASinglePhoto))); group1.Items.Add(new SampleDataItem("FilePicker-PickMultipleFiles", "Pick multiple files", "you can pick multiple files", "Assets/FilePicker.jpg", "pick multiple files", "", group1, typeof(PickMultipleFiles))); group1.Items.Add(new SampleDataItem("FilePicker-PickAFolder", "Pick a folder", "you can pick a folder", "Assets/FilePicker.jpg", "Pick a folder", "", group1, typeof(PickAFolder))); group1.Items.Add(new SampleDataItem("FilePicker-SaveAFile", "Save a file", "you can save a file", "Assets/FilePicker.jpg", "Save a file", "", group1, typeof(SaveAFile))); this.AllGroups.Add(group1); #endregion #region Group2 var group2 = new SampleDataGroup("FileAceess", "Using Windows.Storage API", "File access", "Assets/FileAccess.jpg", ""); group2.Items.Add(new SampleDataItem("FileAceess-CreatingAFile", "Create a file", "Using CreateFileAsync Create a file", "Assets/FileAccess.jpg", "Using CreateFileAsync", "", group2, typeof(CreatingAFile))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingText", "Write And Read A Text", "Using WriteTextAsync,ReadTextAsync Write And Read Text", "Assets/FileAccess.jpg", "Using WriteTextAsync,ReadTextAsync", "", group2, typeof(WritingAndReadingText))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingBytes", "Writing and reading bytes in a file", "Using WriteBufferAsync,ReadBufferAsync Write And Read bytes", "Assets/FileAccess.jpg", "Using WriteBufferAsync,ReadBufferAsync", "", group2, typeof(WritingAndReadingBytes))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingUsingStream", "Writing and reading using a stream", "Using OpenAsync Writing and reading using a stream", "Assets/FileAccess.jpg", "Using OpenAsync", "", group2, typeof(WritingAndReadingUsingStream))); group2.Items.Add(new SampleDataItem("FileAceess-DisplayingFileProperties", "Displaying file properties", "Using GetBasicPropertiesAsync Get File Properties", "Assets/FileAccess.jpg", "Using GetBasicPropertiesAsync", "", group2, typeof(DisplayingFileProperties))); group2.Items.Add(new SampleDataItem("FileAceess-PersistingAccess", "Persisting access to a storage item for future use", "Using MostRecentlyUsedList", "Assets/FileAccess.jpg", "Using MostRecentlyUsedList", "", group2, typeof(PersistingAccess))); group2.Items.Add(new SampleDataItem("FileAceess-CopyAFile", "Copy a file", "Using CopyAsync Copy a file", "Assets/FileAccess.jpg", "Using CopyAsync", "", group2, typeof(CopyAFile))); group2.Items.Add(new SampleDataItem("FileAceess-DeleteAFile", "Delete a file", "Using DeleteAsync Delete a file", "Assets/FileAccess.jpg", "Using DeleteAsync", "", group2, typeof(DeleteAFile))); this.AllGroups.Add(group2); #endregion #region Group3 var group3 = new SampleDataGroup("AccountPictureName", "Use Windows.System.UserProfile API", "Account Picture Name", "Assets/AccountPictureName.jpg", ""); group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserDisplayName", "Get User DisplayName", "Use UserInformation.GetDisplayNameAsync Get User DisplayName", "Assets/AccountPictureName.jpg", "Use UserInformation.GetDisplayNameAsync", "", group3, typeof(GetUserDisplayName))); group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserFirstLastName", "Get First Last Name", "Use UserInformation.GetFirstNameAsync,GetLastNameAsync Get First Name", "Assets/AccountPictureName.jpg", "Use UserInformation.GetFirstNameAsync ", "", group3, typeof(GetUserFirstLastName))); group3.Items.Add(new SampleDataItem("AccountPictureName-GetAccountPicture", "Get Account Picture", "Use UserInformation.GetAccountPicture Get Account Picture", "Assets/AccountPictureName.jpg", "Use UserInformation.GetAccountPicture", "", group3, typeof(GetAccountPicture))); group3.Items.Add(new SampleDataItem("AccountPictureName-SetAccountPictureAndListen", "Set AccountPicture And Listen", "Use UserInformation.SetAccountPicturesAsync Set AccountPicture", "Assets/AccountPictureName.jpg", "Use UserInformation.SetAccountPicturesAsync", "", group3, typeof(SetAccountPictureAndListen))); this.AllGroups.Add(group3); #endregion #region Group4 var group4 = new SampleDataGroup("ApplicationSettings", "ApplicationSettings", " Use the Windows.UI.ApplicationSettings namespace and WinJS.UI.SettingsFlyout", "Assets/ApplicationSettings.jpg", ""); group4.Items.Add(new SampleDataItem("ApplicationSettings-Default", "Default behavior with no settings integration", "Default behavior ", "Assets/ApplicationSettings.jpg", "Default behavior with no settings integration", "", group4, typeof(Default))); group4.Items.Add(new SampleDataItem("ApplicationSettings-AddSettings", "Add settings commands to the settings charm", "Add settings", "Assets/ApplicationSettings.jpg", "Add settings commands to the settings charm ", "", group4, typeof(AddSettings))); this.AllGroups.Add(group4); #endregion #region Group5 var Group5 = new SampleDataGroup("AssociationLaunching", "Use Windows.System.Launcher API", "Association Launching", "Assets/AssociationLaunching.jpg", ""); Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchFile", "Launching a file", "Use Windows.System.Launcher.LaunchFileAsync", "Assets/AssociationLaunching.jpg", "Use Windows.System.Launcher.LaunchFileAsync", "", Group5, typeof(LaunchFile))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchUri", "Launching a URI", "Use Windows.System.Launcher.LaunchUriAsync", "Assets/AssociationLaunching.jpg", "Use Windows.System.Launcher.LaunchUriAsync", "", Group5, typeof(LaunchUri))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveFile", "Receiving a file", "Receiving a file", "Assets/AssociationLaunching.jpg", "Receiving a file", "", Group5, typeof(ReceiveFile))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveUri", "Receiving a URI", "Receiving a URI", "Assets/AssociationLaunching.jpg", "Receiving a URI", "", Group5, typeof(ReceiveUri))); this.AllGroups.Add(Group5); #endregion #region Group6 var Group6 = new SampleDataGroup("BackgroundTransfer", "Use Windows.Networking.BackgroundTransfer API", "BackgroundDownloader And BackgroundUploader", "Assets/BackgroundTransfer.jpg", ""); Group6.Items.Add(new SampleDataItem("BackgroundTransfer-DownloadFile", "Download Files", "Use BackgroundDownloader", "Assets/BackgroundTransfer.jpg", "BackgroundDownloader", "", Group6, typeof(DownloadFile))); Group6.Items.Add(new SampleDataItem("BackgroundTransfer-UploadFile", "Upload Files", "Use BackgroundUploader", "Assets/BackgroundTransfer.jpg", "BackgroundUploader", "", Group6, typeof(UploadFile))); this.AllGroups.Add(Group6); #endregion #region Group7 var Group7 = new SampleDataGroup("Clipboard", "Use Windows.ApplicationModel.DataTransfer API", "ClipboardOperation", "Assets/Clipboard.jpg", ""); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteText", "Copy and paste text", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteText))); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteImage", "Copy and paste an image", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteImage))); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteFile", "Copy and paste files", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteFile))); Group7.Items.Add(new SampleDataItem("Clipboard-OtherClipboardOperation", "Other Clipboard operations", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(OtherClipboardOperation))); this.AllGroups.Add(Group7); #endregion }
5)我们的导航这样就做好了,效果图:
点击 Clipboard
6)复制和粘贴文本
我们使用Clipboard.SetContent设置DataPackage对象到剪贴板,
使用Clipboard.GetContent将复制的内容返回到DataPackageView对象。
使用DataPackageView.GetTextAsync获得粘贴的文本
CopyAndPasteText.xaml的xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <WebView x:Name="Description" Height="210" Width="550" HorizontalAlignment="Left"/> <StackPanel Margin="0,10,0,0" Orientation="Horizontal"> <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"/> <Button x:Name="DisplayResourceMap" Content="Display resource map" Margin="0,0,10,0"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <StackPanel HorizontalAlignment="Left" > <TextBlock x:Name ="OutputText" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" /> <WebView x:Name="OutputHtml" HorizontalAlignment="Left" Height="210" Width="600" /> </StackPanel> </Grid> </Grid>
修改后台代码:
public sealed partial class CopyAndPasteText : Page { 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/logo.jpg"; public CopyAndPasteText() { this.InitializeComponent(); CopyButton.Click += new RoutedEventHandler(CopyButton_Click); PasteButton.Click += new RoutedEventHandler(PasteButton_Click); DisplayResourceMap.Click += new RoutedEventHandler(DisplayResourceMap_Click); Description.NavigateToString(this.htmlFragment); } private async void DisplayResourceMap_Click(object sender, RoutedEventArgs e) { OutputHtml.NavigateToString("<HTML></HTML>"); OutputText.Text = "Keys in the resource map: "; var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); IReadOnlyDictionary<string, RandomAccessStreamReference> resMap = null; try { //获取DataPackageView中的html引用的图像 resMap = await dataPackageView.GetResourceMapAsync(); } catch (Exception ex) { OutputText.Text = "Error retrieving Resource map from Clipboard: " + ex.Message; } if (resMap != null) { if (resMap.Count > 0) { foreach (var item in resMap) { OutputText.Text += Environment.NewLine + "Key: " + item.Key; } } else { OutputText.Text += Environment.NewLine + "Resource map is empty"; } } } private async void PasteButton_Click(object sender, RoutedEventArgs e) { OutputText.Text = "Content in the clipboard: "; //获取剪贴板存储的内容,返回DataPackageView var 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) { OutputText.Text = "Error retrieving Text format from Clipboard: " + ex.Message; } } else { OutputText.Text = "Text: " + Environment.NewLine + "Text format is not available in clipboard"; } if (dataPackageView.Contains(StandardDataFormats.Html)) { string htmlFormat = null; try { //获取DataPackageView的html htmlFormat = await dataPackageView.GetHtmlFormatAsync(); } catch (Exception ex) { OutputText.Text = "Error retrieving HTML format from Clipboard: " + ex.Message; } if (htmlFormat != null) { string htmlFragment = HtmlFormatHelper.GetStaticFragment(htmlFormat); OutputHtml.NavigateToString("Html:<br/ > " + htmlFragment); } } else { OutputHtml.NavigateToString("Html:<br/ > HTML format is not available in clipboard"); } } private void CopyButton_Click(object sender, RoutedEventArgs e) { OutputText.Text = ""; OutputHtml.NavigateToString("<HTML></HTML>"); //使用html内容的字符串,并添加必要的表头,来保证剪贴板格式操作无误 string htmlFormat = HtmlFormatHelper.CreateHtmlFormat(this.htmlFragment); var dataPackage = new DataPackage(); //添加html内容 dataPackage.SetHtmlFormat(htmlFormat); // 将html格式的数据转换为包含从html提取的文本内容的字符串 string plainText = HtmlUtilities.ConvertToText(this.htmlFragment); //添加文本 dataPackage.SetText(plainText); var imgUri = new Uri(imgSrc); //将本地图片 var imgRef = RandomAccessStreamReference.CreateFromUri(imgUri); //将uri映射到文件 dataPackage.ResourceMap[imgSrc] = imgRef; try { // 复制当前对象到剪切板 Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); OutputText.Text = "Text and HTML formats have been copied to clipboard. "; } catch (Exception ex) { OutputText.Text = "Error copying content to Clipboard: " + ex.Message + ". Try again"; } } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } }
效果图
点击Paste
7)复制和粘贴图像
我们使用Clipboard.SetContent设置DataPackage对象到剪贴板,
使用Clipboard.GetContent将复制的内容返回到DataPackageView对象。
使用DataPackageView.GetBitmapAsync获得粘贴的图像
修改CopyAndPasteImage.xaml的xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel> <TextBlock x:Name="Description" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap"> The DataPackage can also hold a bitmap. Select image using item picker, copy it to the clipboard, and then paste it back into the application. Image can also be provided via delayed rendering, when source app doesn't want to supply data until target app requests it. </TextBlock> <StackPanel Margin="0,10,0,0" Orientation="Horizontal"> <Button x:Name="CopyButton" Content="Select image and copy" Margin="0,0,10,0"/> <Button x:Name="CopyWithDelayRenderingButton" Content="Select image and copy using delayed rendering" Margin="0,0,10,0"/> <Button x:Name="PasteButton" Content="Paste" Margin="0,0,10,0"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <StackPanel Orientation="Vertical"> <TextBlock x:Name ="OutputText" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" /> <Image x:Name="ImageHolder" HorizontalAlignment="Left" Visibility="Collapsed" MaxHeight="300" MaxWidth="400"/> </StackPanel> </Grid> </Grid>
修改后台代码:
public sealed partial class CopyAndPasteImage : Page { private StorageFile imageFile = null; public CopyAndPasteImage() { this.InitializeComponent(); CopyButton.Click += new RoutedEventHandler(CopyButton_Click); PasteButton.Click += new RoutedEventHandler(PasteButton_Click); CopyWithDelayRenderingButton.Click += new RoutedEventHandler(CopyWithDelayRenderingButton_Click); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } void CopyButton_Click(object sender, RoutedEventArgs e) { this.CopyBitmap(false); } void CopyWithDelayRenderingButton_Click(object sender, RoutedEventArgs e) { this.CopyBitmap(true); } async void PasteButton_Click(object sender, RoutedEventArgs e) { // Get the bitmap and display it. var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.Bitmap)) { IRandomAccessStreamReference imageReceived = null; try { //获取DataPackageView的位图图像 imageReceived = await dataPackageView.GetBitmapAsync(); } catch (Exception ex) { OutputText.Text = "Error retrieving image from Clipboard: " + ex.Message; } if (imageReceived != null) { var imageStream = await imageReceived.OpenReadAsync(); var bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); ImageHolder.Source = bitmapImage; ImageHolder.Visibility = Visibility.Visible; OutputText.Text = "Image is retrieved from the clipboard and pasted successfully."; } } else { OutputText.Text = "Bitmap format is not available in clipboard"; ImageHolder.Visibility = Visibility.Collapsed; } } async private void OnDeferredImageRequestedHandler(DataProviderRequest request) { if (this.imageFile != null) { // Since this method is using "await" prior to setting the data in DataPackage, // deferral object must be used var deferral = request.GetDeferral(); // Surround try catch to ensure that we always call Complete on defferal. try { var imageStream = await this.imageFile.OpenAsync(FileAccessMode.Read); // Decode the image 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 { deferral.Complete(); } await log(OutputText, "Image has been set via deferral"); } else { await log(OutputText, "Error: imageFile is null"); } } async private void CopyBitmap(bool isDelayRendered) { 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(); // Use one click handler for two operations: regular copy and copy using delayed rendering // Differentiate the case by the button name if (isDelayRendered) { this.imageFile = imageFile; dataPackage.SetDataProvider(StandardDataFormats.Bitmap, OnDeferredImageRequestedHandler); OutputText.Text = "Image has been copied using delayed rendering"; } else { dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageFile)); OutputText.Text = "Image has been copied"; } try { Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); } catch (Exception ex) { // Copying data to Clipboard can potentially fail - for example, if another application is holding Clipboard open OutputText.Text = "Error copying content to Clipboard: " + ex.Message + ". Try again"; } } else { OutputText.Text = "No image was selected."; } } async private Task log(TextBlock textBlock, string msg) { // This function should be called when a back-ground thread tries to output log to the UI await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { textBlock.Text += Environment.NewLine + msg; }); } }
效果图:
点击 Paste
8)复制和粘贴文件
我们使用Clipboard.SetContent设置DataPackage对象到剪贴板,
使用Clipboard.GetContent将复制的内容返回到DataPackageView对象。
使用DataPackage.SetStorageItems设置要粘贴的文件
使用DataPackageView.GetStorageItemsAsync从剪切板获得粘贴的文件
修改CopyAndPasteFile.xaml的xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel> <TextBlock x:Name="Description" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" > The DataPackage can also hold files. Select files using the picker, copy them to the clipboard, and then paste the files. This will copy the files into this app's local state folder. </TextBlock> <StackPanel Margin="0,10,0,0" Orientation="Horizontal"> <Button x:Name="CopyButton" Content="Select file and copy" Margin="0,0,10,0"/> <Button x:Name="PasteButton" Content="Paste" Margin="0,0,10,0"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock x:Name ="OutputText" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" /> </Grid> </Grid>
修改后台代码:
public sealed partial class CopyAndPasteFile : Page { public CopyAndPasteFile() { this.InitializeComponent(); CopyButton.Click += new RoutedEventHandler(CopyButton_Click); PasteButton.Click += new RoutedEventHandler(PasteButton_Click); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } async void CopyButton_Click(object sender, RoutedEventArgs e) { OutputText.Text = "Storage Items: "; 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); // Request a copy operation from targets that support different file operations, like Windows Explorer dataPackage.RequestedOperation = DataPackageOperation.Copy; try { Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); } catch (Exception ex) { // Copying data to Clipboard can potentially fail - for example, if another application is holding Clipboard open OutputText.Text = "Error copying content to Clipboard: " + ex.Message + ". Try again"; } } else { OutputText.Text += "No file was selected."; } } async void PasteButton_Click(object sender, RoutedEventArgs e) { // Get data package from clipboard var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.StorageItems)) { IReadOnlyList<IStorageItem> storageItems = null; try { storageItems = await dataPackageView.GetStorageItemsAsync(); } catch (Exception ex) { OutputText.Text = "Error retrieving file(s) from Clipboard: " + ex.Message; } if (storageItems != null) { OutputText.Text = "Pasting following" + storageItems.Count + " file(s) to the folder\t\n " + ApplicationData.Current.LocalFolder.Path + Environment.NewLine; var operation = dataPackageView.RequestedOperation; OutputText.Text += "Requested Operation: "; switch (operation) { case DataPackageOperation.Copy: OutputText.Text += "Copy"; break; case DataPackageOperation.Link: OutputText.Text += "Link"; break; case DataPackageOperation.Move: OutputText.Text += "Move"; break; case DataPackageOperation.None: OutputText.Text += "None"; break; default: OutputText.Text += "Unknown"; break; } OutputText.Text += Environment.NewLine; // Iterate through each item in the collection foreach (var storageItem in storageItems) { var file = storageItem as StorageFile; if (file != null) { // Copy the file var newFile = await file.CopyAsync(ApplicationData.Current.LocalFolder, file.Name, NameCollisionOption.ReplaceExisting); if (newFile != null) { OutputText.Text += file.Name + Environment.NewLine; } } else { var folder = storageItem as StorageFolder; if (folder != null) { // Skipping folders for brevity sake OutputText.Text += folder.Path + " is a folder, skipping" + Environment.NewLine; } } } } } else { OutputText.Text = "StorageItems format is not available in clipboard"; } } }
效果图如下:
点击 Paste
9)获得剪贴板的格式和监视剪贴板的变化
我们使用Clipboard.SetContent设置DataPackage对象到剪贴板,
使用Clipboard.GetContent将复制的内容返回到DataPackageView对象。
使用DataPackage. Clipboard.Clear清空剪贴板
使用Clipboard.ContentChanged来监视剪贴板的变化
修改OtherClipboardOperation.xaml的xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock x:Name="Description" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" > Your application can register for clipboard update notifications to decide whether to enable Paste operation. Updates occur any time user copies something onto clipboard, or when it's emptied. In this scenario, you will see a list of all available formats on clipboard. If check box is checked, the list will appear automatically whenever clipboard update notification is received. Otherwise, use "Show Clipboard Formats" button. </TextBlock> <StackPanel Margin="0,10,0,0" Orientation="Horizontal"> <Button x:Name="ShowFormatButton" Content="Show Clipboard Formats" Margin="0,0,10,0"/> <Button x:Name="EmptyClipboardButton" Content="Empty Clipboard" Margin="0,0,10,0"/> <Button x:Name="ClearOutputButton" Content="Clear Output" Margin="0,0,10,0"/> </StackPanel> <CheckBox x:Name="RegisterClipboardContentChange" Content="Register Clipboard Content Change"/> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <StackPanel HorizontalAlignment="Left"> <TextBlock x:Name ="OutputText" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" Text="" /> <TextBlock x:Name ="DisplayFormatOutputText" Style="{StaticResource BodyTextStyle}" TextWrapping="Wrap" Text="" /> </StackPanel> </Grid> </Grid>
修改后台代码:
public sealed partial class OtherClipboardOperation : Page { private bool isApplicationWindowActive = true; private bool containsUnprocessedNotifications = false; SplitPage sp = SplitPage.Current; public OtherClipboardOperation() { this.InitializeComponent(); ShowFormatButton.Click += new RoutedEventHandler(ShowFormatButton_Click); EmptyClipboardButton.Click += new RoutedEventHandler(EmptyClipboardButton_Click); RegisterClipboardContentChange.Checked += new RoutedEventHandler(RegisterClipboardContentChange_Check); RegisterClipboardContentChange.Unchecked += new RoutedEventHandler(RegisterClipboardContentChange_UnCheck); ClearOutputButton.Click += new RoutedEventHandler(ClearOutputButton_Click); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { if (sp.isClipboardContentChangeChecked) { RegisterClipboardContentChange.IsChecked = true; } if (sp.needToPrintClipboardFormat) { this.DisplayFormats(Windows.ApplicationModel.DataTransfer.Clipboard.GetContent()); } } void ShowFormatButton_Click(object sender, RoutedEventArgs e) { var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent(); this.DisplayFormats(dataPackageView); } void EmptyClipboardButton_Click(object sender, RoutedEventArgs e) { this.DisplayFormatOutputText.Text = ""; try { //移除剪贴板所有数据 Windows.ApplicationModel.DataTransfer.Clipboard.Clear(); OutputText.Text = "Clipboard has been emptied."; } catch (Exception ex) { OutputText.Text = "Error emptying Clipboard: " + ex.Message + ". Try again"; } } void RegisterClipboardContentChange_Check(object sender, RoutedEventArgs e) { if (!sp.isClipboardContentChangeChecked) { sp.isClipboardContentChangeChecked = true; sp.clipboardContentChanged = new EventHandler<object>(this.RegisterClipboardChangeEventHandler); Windows.ApplicationModel.DataTransfer.Clipboard.ContentChanged += sp.clipboardContentChanged; Window.Current.CoreWindow.VisibilityChanged += new TypedEventHandler<CoreWindow, VisibilityChangedEventArgs>(CoreWindow_VisibilityChanged); OutputText.Text = "Successfully registered for clipboard update notification."; } } void RegisterClipboardContentChange_UnCheck(object sender, RoutedEventArgs e) { this.ClearOutput(); sp.isClipboardContentChangeChecked = false; Windows.ApplicationModel.DataTransfer.Clipboard.ContentChanged -= sp.clipboardContentChanged; Window.Current.CoreWindow.VisibilityChanged -= new TypedEventHandler<CoreWindow, VisibilityChangedEventArgs>(CoreWindow_VisibilityChanged); OutputText.Text = "Successfully un-registered for clipboard update notification."; } void ClearOutputButton_Click(object sender, RoutedEventArgs e) { this.ClearOutput(); } private void ClearOutput() { OutputText.Text = ""; DisplayFormatOutputText.Text = ""; } private void DisplayFormats(DataPackageView dataPackageView) { if (dataPackageView != null && dataPackageView.AvailableFormats.Count > 0) { DisplayFormatOutputText.Text = "Available formats in the clipboard: "; var availableFormats = dataPackageView.AvailableFormats.GetEnumerator(); while (availableFormats.MoveNext()) { DisplayFormatOutputText.Text += Environment.NewLine + availableFormats.Current; } } else { OutputText.Text = "Clipboard is empty"; } } private void RegisterClipboardChangeEventHandler(object sender, object e) { // If user is not in when clipboard content is changed, this flag will ensure the clipboard format gets printed out when user navigates to it sp.needToPrintClipboardFormat = true; if (this.isApplicationWindowActive) { OutputText.Text =String.Format("Clipboard content has been changed. Please select 'other clipboard operations' scenario to see the list of available formats."); this.DisplayFormats(Windows.ApplicationModel.DataTransfer.Clipboard.GetContent()); } else { OutputText.Text = String.Format("Clipboard content has been changed while the app was at background. Please select 'other clipboard operations' scenario to see the list of available formats."); // Background applications can't access clipboard // Deferring processing of update notification till later this.containsUnprocessedNotifications = true; } } private void CoreWindow_VisibilityChanged(CoreWindow sender, VisibilityChangedEventArgs e) { if (e.Visible) { // Application's main window has been activated (received focus), and therefore the application can now access clipboard this.isApplicationWindowActive = true; if (this.containsUnprocessedNotifications) { this.DisplayFormats(Windows.ApplicationModel.DataTransfer.Clipboard.GetContent()); this.containsUnprocessedNotifications = false; } } else { // Application's main window has been deactivated (lost focus), and therefore the application can no longer access Clipboard this.isApplicationWindowActive = false; } } }
效果图:
未完待续,敬请期待...
转载请注明出处:http://www.cnblogs.com/refactor/