MS/WPF-Samples/Clipboard源码分析

本文深入分析了WPF中关于剪切板操作的两个示例项目ClipboardViewer和ClipboardSpy。主要内容包括:1) 突破点在于理解`Loaded`事件在窗口生命周期中的作用;2) 探讨了如何从剪切板获取和设置不同格式的数据;3) 介绍了可空类型和空合并运算符在C#中的应用。文章通过实例代码加深了对WPF剪切板功能的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最近打算自己开发一款Windows平台的软件,但查看相关文档之后仍对一些功能不够熟练,偶然间发现Github上有微软官方发布的实例代码,故打算研究研究这些代码弄懂WPF平台上开发的一些细节问题。

我决定随缘研究这些代码,毕竟有这么多,就先挑自己觉得有用的、用得上的示例来研究好了。

附上项目下载地址,大家可以下载后参照着来看:WPF-Samples

ClipboardViewer

在Clipboard目录下共有两个示例项目,先分析这个剪切板查看器,运行后的界面如下:

可以看到界面中大体上就是显示及设置剪切板内容和格式的功能,Xaml代码看了看有些冗长,而且基本上就是普通的布局,甚至连数据绑定都没有,因此直接对c#代码进行分析。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    // This is called when UI is laid out, rendered and ready for interaction.
    private void WindowLoaded(object sender, RoutedEventArgs args)
    {
        // Check the current Clipboard data format status
        RefreshClipboardDataFormat();

        // Set the text copy information on RichTextBox
        SetTextOnRichTextBox("Please type clipboard copy data here!");
    }

	// Update the data format status and describe all available data formats
    private void RefreshClipboardDataFormat()
    {
        clipboardInfo.Clear();

        lbPasteDataFormat.Items.Clear();

        var dataObject = GetDataObjectFromClipboard();

        if (dataObject == null)
        {
            clipboardInfo.Text = "Can't access clipboard now! Please click Refresh button again.";
        }
        else
        {
            // Check the data format whether it is on Clipboard or not
            cbAudio.IsChecked = dataObject.GetDataPresent(DataFormats.WaveAudio);
            cbFileDropList.IsChecked = dataObject.GetDataPresent(DataFormats.FileDrop);
            cbImage.IsChecked = dataObject.GetDataPresent(DataFormats.Bitmap);
            cbText.IsChecked = dataObject.GetDataPresent(DataFormats.Text);
            cbRtf.IsChecked = dataObject.GetDataPresent(DataFormats.Rtf);
            cbXaml.IsChecked = dataObject.GetDataPresent(DataFormats.Xaml);

            // Update the data format into the information panel
            UpdateAvailableDataFormats(dataObject);
        }
    }

	// Set the plain text on RichTextBox
    private void SetTextOnRichTextBox(string text)
    {
        var document = richTextBox.Document;
        var textRange = new TextRange(document.ContentStart, document.ContentEnd) {Text = text};
        richTextBox.Focus();
        richTextBox.SelectAll();
    }
}

以上代码中,构造函数没什么说的。但是WindowLoaded函数则让我有些疑惑,我明明没有在构造函数中添加Loaded事件,而且在Window类中也并无与Load相关的事件。于是我在这个方法内部加了断点发现果然在窗口加载完毕也就是弹出窗口但内容却一片空白的情况下执行到了断点处,那么这应该就涉及到窗口的生命周期的问题了。

Window生命周期图

看了一下官方文档,又回头看了看Window类的方法,这个Loaded方法到底去哪儿了呢?

终于,查阅API文档,发现它是继承了FrameworkElement,在该类的Loaded方法描述中我发现了同样的一句话:

Occurs when the element is laid out, rendered, and ready for interaction.

那么就是它了,但还有一个问题,不同名的函数为什么可以调用呢?

首先我注意到了RoutedEventArgs这个类型的参数,我想是不是参数不同导致系统可以直接识别这个方法就是执行到Loaded之后用户想要运行的方法呢?但我观察其他事件接收函数也同样是这个类型的参数,那系统还怎么识别呢?但我还抱有侥幸心理,于是。。。

我只是改了一下名字而已,三个错误。。那也就排除了系统可以识别参数的选项,同时似乎也说明了这是系统内置的方法名,但我又一次翻看系统API,还是没有找到该方法名。

再次阅读该错误,说是MainWindow没有WindowLoaded的定义,那就是说有这个声明了。果然,在Xaml中发现了这个声明。。。哎,自作聪明。。

好了,虽然绕了一大圈,但终究解决了疑问并且学到了知识不是么,下面正式进入主题。可以看到在Loaded方法中首先检查了剪切板中数据的格式,然后在富文本编辑框中输入提示信息,下面先分析RefreshClipboardDataFormat方法。

1、clipboardInfo是界面中右上方的显示剪切板内容的一大块文本框的name,清空它的内容。

2、lbPasteDataFormat是Paste(Get) Format:下面显示剪切板所含对象的列表,清空所有项目。

3、GetDataObjectFromClipboard方法从剪切版中获取所含数据的对象

// Get DataObject from the system clipboard
private IDataObject GetDataObjectFromClipboard()
{
    IDataObject dataObject;

    try
    {
        dataObject = Clipboard.GetDataObject();
    }
    catch (COMException)
    {
        // Clipboard.GetDataObject can be failed by opening the system clipboard 
        // from other or processing clipboard operation like as setting data on clipboard
        dataObject = null;
    }

    return dataObject;
}

该方法从剪切板获取数据并返回。注意到该方法的返回值为IDataObject,该接口为Windows下面的,那应该是系统为我们定义的接口。

4、根据从剪切板获取的数据设置界面中左上角多选框的状态,其中DataFormates类提供了一组预定义数据格式名

字段 字段值 描述
Bitmap “Bitmap” 指定 Microsoft Windows 位图数据格式。
CommaSeparatedValue “CSV” 指定以逗号分隔的值 (CSV) 数据格式。
Dib “DeviceIndependentBitmap” 指定与设备无关位图 (DIB) 数据格式。
Dif “DataInterchangeFormat” 指定 Windows 数据交换格式 (DIF) 数据格式。
EnhancedMetafile
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值