1. 程式人生 > >背水一戰 Windows 10 (102) - 應用間通信: 剪切板

背水一戰 Windows 10 (102) - 應用間通信: 剪切板

exceptio 文件復制 cep 源碼 present bcd str tns 觸發

[源碼下載]


背水一戰 Windows 10 (102) - 應用間通信: 剪切板



作者:webabcd


介紹
背水一戰 Windows 10 之 應用間通信

  • 剪切板 - 基礎, 復制/粘貼 text 內容
  • 剪切板 - 復制/粘貼 html 內容
  • 剪切板 - 復制/粘貼 bitmap 內容,延遲復制
  • 剪切板 - 復制/粘貼文件



示例
1、演示剪切板的基礎知識,以及如何復制 text 數據到剪切板,以及如何從剪切板中獲取 text 數據
App2AppCommunication/Clipboard.xaml

<Page
    x:Class="Windows10.App2AppCommunication.Clipboard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.App2AppCommunication" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="btnCopyText" Content="復制一段文本到剪切板" Click="btnCopyText_Click" Margin="5" /> <
Button Name="btnPasteText" Content="粘貼剪切板中的文本" Click="btnPasteText_Click" Margin="5" /> <Button Name="btnShowAvailableFormats" Content="獲取剪切板中包含的數據的格式類型" Click="btnShowAvailableFormats_Click" Margin="5" /> <Button Name="btnClear" Content="清除剪切板中的全部內容" Click="btnClear_Click" Margin="5" /> </StackPanel> </Grid> </Page>

App2AppCommunication/Clipboard.xaml.cs

/*
 * 演示剪切板的基礎知識,以及如何復制 text 數據到剪切板,以及如何從剪切板中獲取 text 數據 
 * 
 * Clipboard - 剪切板
 *     SetContent() - 將指定的 DataPackage 存入剪切板
 *     GetContent() - 從剪切板中獲取 DataPackage 對象
 *     Clear() - 清除剪切板中的全部數據
 *     Flush() - 正常情況下,關閉 app 後,此 app 保存到剪切板的數據就會消失;調用此方法後,即使關閉 app,剪切板中的數據也不會消失
 *     ContentChanged - 剪切板中的數據發生變化時所觸發的事件
 *     
 * DataPackage - 用於封裝 Clipboard 或 ShareContract 的數據(詳細說明見“分享”的 Demo)
 *     SetText(), SetWebLink(), SetApplicationLink(), SetHtmlFormat(), SetBitmap(), SetStorageItems(), SetData(), SetDataProvider() - 設置復制到剪切板的各種格式的數據(註:一個 DataPackage 可以有多種不同格式的數據)
 *     RequestedOperation - 操作類型(DataPackageOperation 枚舉: None, Copy, Move, Link),沒發現此屬性有任何作用
 *     
 * DataPackageView - DataPackage 對象的只讀版本,從剪切板獲取數據或者共享目標接收數據均通過此對象來獲取 DataPackage 對象的數據(詳細說明見“分享”的 Demo)
 */

using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Windows10.App2AppCommunication
{
    public sealed partial class Clipboard : Page
    {
        public Clipboard()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            Windows.ApplicationModel.DataTransfer.Clipboard.ContentChanged += Clipboard_ContentChanged;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            Windows.ApplicationModel.DataTransfer.Clipboard.ContentChanged -= Clipboard_ContentChanged;
        }

        void Clipboard_ContentChanged(object sender, object e)
        {
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "剪切板中的內容發生了變化";
        }

        // 復制一段文本到剪切板
        private void btnCopyText_Click(object sender, RoutedEventArgs e)
        {
            // 構造保存到剪切板的 DataPackage 對象
            DataPackage dataPackage = new DataPackage();
            dataPackage.SetText("I am webabcd: " + DateTime.Now.ToString());

            try
            {
                Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage); // 保存 DataPackage 對象到剪切板
                Windows.ApplicationModel.DataTransfer.Clipboard.Flush(); // 當此 app 關閉後,依然保留剪切板中的數據
                lblMsg.Text = "已將內容復制到剪切板";
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }

        // 顯示剪切板中的文本數據
        private async void btnPasteText_Click(object sender, RoutedEventArgs e)
        {
            // 獲取剪切板中的數據
            DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

            // 如果剪切板中有文本數據,則獲取並顯示該文本
            if (dataPackageView.Contains(StandardDataFormats.Text))
            {
                try
                {
                    string text = await dataPackageView.GetTextAsync();
                    lblMsg.Text = text;
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();
                }
            }
            else
            {
                lblMsg.Text = "剪切板中無文本內容";
            }
        }

        // 顯示剪切板中包含的數據的格式類型,可能會有 StandardDataFormats 枚舉的格式,也可能會有自定義的格式(關於自定義格式可以參見“分享”的 Demo)
        private void btnShowAvailableFormats_Click(object sender, RoutedEventArgs e)
        {
            DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
            if (dataPackageView != null && dataPackageView.AvailableFormats.Count > 0)
            {
                var availableFormats = dataPackageView.AvailableFormats.GetEnumerator();
                while (availableFormats.MoveNext())
                {
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += availableFormats.Current;
                }
            }
            else
            {
                lblMsg.Text = "剪切板中無任何內容";
            }
        }

        // 清除剪切板中的全部數據
        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            Windows.ApplicationModel.DataTransfer.Clipboard.Clear();
        }
    }
}


2、演示如何復制 html 數據到剪切板,以及如何從剪切板中獲取 html 數據
App2AppCommunication/ClipboardCopyHtml.xaml

<Page
    x:Class="Windows10.App2AppCommunication.ClipboardCopyHtml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.App2AppCommunication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" Margin="5" />

            <Button Name="btnCopyHtml" Content="復制一段 html 到剪切板" Click="btnCopyHtml_Click" Margin="5" />

            <Button Name="btnPasteHtml" Content="粘貼剪切板中的 html" Click="btnPasteHtml_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

App2AppCommunication/ClipboardCopyHtml.xaml.cs

/*
 * 演示如何復制 html 數據到剪切板,以及如何從剪切板中獲取 html 數據 
 * 
 * HtmlFormatHelper - 在 Clipboard 中傳遞 html 數據或在 ShareContract 中傳遞 html 數據時的幫助類
 *     CreateHtmlFormat() - 封裝需要傳遞的 html 字符串,以便以 html 方式傳遞數據
 *     GetStaticFragment() - 解封裝傳遞過來的經過封裝的 html 數據,從而獲取初始需要傳遞的 html 字符串
 */

using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows10.App2AppCommunication
{
    public sealed partial class ClipboardCopyHtml : Page
    {
        public ClipboardCopyHtml()
        {
            this.InitializeComponent();
        }

        // 復制 html 字符串到剪切板
        private void btnCopyHtml_Click(object sender, RoutedEventArgs e)
        {
            DataPackage dataPackage = new DataPackage();
            // 封裝一下需要復制的 html 數據,以便以 html 的方式將數據復制到剪切板
            string htmlFormat = HtmlFormatHelper.CreateHtmlFormat("<body>I am webabcd</body>");
            dataPackage.SetHtmlFormat(htmlFormat);

            try
            {
                Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage);
                lblMsg.Text = "已將內容復制到剪切板";
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }

        // 顯示剪切板中的 html 數據
        private async void btnPasteHtml_Click(object sender, RoutedEventArgs e)
        {
            DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

            if (dataPackageView.Contains(StandardDataFormats.Html))
            {
                try
                {
                    // 封裝後的數據
                    string htmlFormat = await dataPackageView.GetHtmlFormatAsync();
                    // 封裝前的數據
                    string htmlFragment = HtmlFormatHelper.GetStaticFragment(htmlFormat);

                    lblMsg.Text = "htmlFormat(封裝後的數據): ";
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += htmlFormat;
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += "htmlFragment(封裝前的數據): ";
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += htmlFragment;
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();
                }
            }
            else
            {
                lblMsg.Text = "剪切板中無 html 內容";
            }
        }
    }
}


3、演示如何復制圖片內容剪切板,以及如何從剪切板中獲取圖片內容;演示如何通過 SetDataProvider() 延遲數據的復制,即在“粘貼”操作觸發後由數據提供器生成相關數據
App2AppCommunication/ClipboardCopyImage.xaml

<Page
    x:Class="Windows10.App2AppCommunication.ClipboardCopyImage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.App2AppCommunication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" Margin="5" />
            <Image Name="imgBitmap" Stretch="None" HorizontalAlignment="Left" Margin="5" />

            <Button Name="btnCopyImage" Content="復制圖片內容到剪切板" Click="btnCopyImage_Click" Margin="5" />

            <Button Name="btnCopyImageWithDeferral" Content="復制數據提供器到剪切板,當“粘貼”操作被觸發時由數據提供器生成用於粘貼的圖片數據" Click="btnCopyImageWithDeferral_Click" Margin="5" />

            <Button Name="btnPasteImage" Content="粘貼剪切板中的圖片內容" Click="btnPasteImage_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

App2AppCommunication/ClipboardCopyImage.xaml.cs

/*
 * 1、演示如何復制圖片內容剪切板,以及如何從剪切板中獲取圖片內容
 * 2、演示如何通過 SetDataProvider() 延遲數據的復制,即在“粘貼”操作觸發後由數據提供器生成相關數據
 */

using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace Windows10.App2AppCommunication
{
    public sealed partial class ClipboardCopyImage : Page
    {
        public ClipboardCopyImage()
        {
            this.InitializeComponent();
        }

        // 復制圖片內容到剪切板
        private void btnCopyImage_Click(object sender, RoutedEventArgs e)
        {
            DataPackage dataPackage = new DataPackage();
            dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/StoreLogo.png", UriKind.Absolute)));

            try
            {
                Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage);
                lblMsg.Text = "已將內容復制到剪切板";
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }

        // 延遲復制
        private async void btnCopyImageWithDeferral_Click(object sender, RoutedEventArgs e)
        {
            StorageFile imageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/StoreLogo.png", UriKind.Absolute));

            DataPackage dataPackage = new DataPackage();
            dataPackage.SetDataProvider(StandardDataFormats.Bitmap, async (request) =>
            {
                /*
                 * 當從剪切板中獲取 StandardDataFormats.Bitmap 數據時,會執行到此處以提供相關數據
                 */

                if (imageFile != null)
                {
                    // 開始異步處理
                    var deferral = request.GetDeferral();

                    try
                    {
                        using (var imageStream = await imageFile.OpenAsync(FileAccessMode.Read))
                        {
                            // 將圖片縮小一倍
                            BitmapDecoder imageDecoder = await BitmapDecoder.CreateAsync(imageStream);
                            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));

                            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                lblMsg.Text = "數據已生成";
                            });
                        }
                    }
                    finally
                    {
                        // 通知系統已完成異步操作
                        deferral.Complete();
                    }
                }
            });

            try
            {
                Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage);
                lblMsg.Text = "已將數據提供器復制到剪切板,在“粘貼”操作時才會生成數據";
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }

        // 顯示剪切板中的圖片內容
        private async void btnPasteImage_Click(object sender, RoutedEventArgs e)
        {
            DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

            if (dataPackageView.Contains(StandardDataFormats.Bitmap))
            {
                try
                {
                    IRandomAccessStreamReference randomStream = await dataPackageView.GetBitmapAsync();
                    if (randomStream != null)
                    {
                        using (IRandomAccessStreamWithContentType imageStream = await randomStream.OpenReadAsync())
                        {
                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.SetSource(imageStream);
                            imgBitmap.Source = bitmapImage;
                        }
                    }
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();
                }
            }
            else
            {
                lblMsg.Text = "剪切板中無 bitmap 內容";
            }
        }
    }
}


4、演示如何復制指定的文件到剪切板,以及如何從剪切板中獲取文件並保存到指定的路徑
App2AppCommunication/ClipboardCopyFile.xaml

<Page
    x:Class="Windows10.App2AppCommunication.ClipboardCopyFile"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.App2AppCommunication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" TextWrapping="Wrap" Margin="5" />

            <Button Name="btnCopyFile" Content="復制一個文件到剪切板" Click="btnCopyFile_Click" Margin="5" />

            <Button Name="btnPasteFile" Content="粘貼剪切板中的文件到指定的路徑" Click="btnPasteFile_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

App2AppCommunication/ClipboardCopyFile.xaml.cs

/*
 * 演示如何復制指定的文件到剪切板,以及如何從剪切板中獲取文件並保存到指定的路徑 
 */

using System;
using System.Linq;
using System.Collections.Generic;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows10.App2AppCommunication
{
    public sealed partial class ClipboardCopyFile : Page
    {
        public ClipboardCopyFile()
        {
            this.InitializeComponent();
        }

        // 保存文件到剪切板
        private async void btnCopyFile_Click(object sender, RoutedEventArgs e)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdTest\clipboard.txt", CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(file, "I am webabcd: " + DateTime.Now.ToString());

            DataPackage dataPackage = new DataPackage();
            dataPackage.SetStorageItems(new List<StorageFile>() { file });

            dataPackage.RequestedOperation = DataPackageOperation.Move;
            try
            {
                Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage);
                lblMsg.Text = "已將文件復制到剪切板";
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }

        // 從剪切板中獲取文件並保存到指定的路徑 
        private async void btnPasteFile_Click(object sender, RoutedEventArgs e)
        {
            DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

            if (dataPackageView.Contains(StandardDataFormats.StorageItems))
            {
                try
                {
                    IReadOnlyList<IStorageItem> storageItems = await dataPackageView.GetStorageItemsAsync();
                    StorageFile file = storageItems.First() as StorageFile;
                    if (file != null)
                    {
                        StorageFile newFile = await file.CopyAsync(ApplicationData.Current.TemporaryFolder, file.Name, NameCollisionOption.ReplaceExisting);
                        if (newFile != null)
                        {
                            lblMsg.Text = string.Format("已將文件從{0}復制到{1}", file.Path, newFile.Path);
                        }
                    }
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();
                }
            }
            else
            {
                lblMsg.Text = "剪切板中無 StorageItems 內容";
            }
        }
    }
}



OK
[源碼下載]

背水一戰 Windows 10 (102) - 應用間通信: 剪切板