文章目录
最近打算自己开发一款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类的方法,这个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 | “EnhancedMetafile” |