原創(chuàng)|其它|編輯:郝浩|2012-08-23 21:51:18.000|閱讀 345 次
概述:本篇文章是WPF 4.5新特征系列的一部分,我們將一起探秘WPF 4.5里“事件的標(biāo)記擴(kuò)展”。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
本篇文章是WPF 4.5新特征系列的一部分,我們將一起探秘WPF 4.5里“事件的標(biāo)記擴(kuò)展”。更多WPF4.5探秘系列文章 WPF控件
標(biāo)記擴(kuò)展是什么?用在什么場(chǎng)景?
正如 Rob 指出,對(duì)于在XAML 中的標(biāo)記擴(kuò)展可以提供值。在這種情況下,也會(huì)提供一個(gè)委托,WPF 框架本身并不定義要用于事件的標(biāo)記擴(kuò)展。
在我看來(lái),這個(gè)特性將使用新的場(chǎng)景。事實(shí)上,對(duì)于某些人創(chuàng)建這樣的擴(kuò)展場(chǎng)景是一種夢(mèng)想,就是在空間上引發(fā)事件時(shí)觸發(fā)一個(gè)動(dòng)作。除了記住哪個(gè)命名空間中添加和使用行為與觸發(fā),開發(fā)人員只需要?jiǎng)?chuàng)建一個(gè)標(biāo)記擴(kuò)展,就像他將創(chuàng)建一個(gè)轉(zhuǎn)換器。當(dāng)然有一個(gè)最主要的缺點(diǎn):不支持混合。如果你也樣是一個(gè)Blend的粉絲,你就會(huì)繼續(xù)使用behavior/trigger,因?yàn)樗恍枰?jiǎn)單拖拽即可。因此,很多人覺得它不會(huì)過(guò)時(shí),這依舊是一個(gè)指的記住的好特性和選擇。
如何使用標(biāo)記擴(kuò)展?
這次,很明顯不能像WPF的其他特性一樣的使用。
作為一個(gè)標(biāo)記擴(kuò)展,一個(gè)類繼承了標(biāo)記擴(kuò)展,并實(shí)現(xiàn)抽象為ProvideValue方法。這就是所謂的框架,它提供了一個(gè)IServiceProvider的對(duì)象作為參數(shù)。
這serviceProvider是一個(gè)依賴解析器,你可以使用它來(lái)獲取一個(gè)命名IProvideValueTarget的服務(wù),然后會(huì)被用來(lái)獲取屬性的MarkupExtension (你可以得到它的目標(biāo)對(duì)象)的目標(biāo)。
這個(gè)屬性是事件活動(dòng)的訪問(wèn)器(當(dāng)你訂閱的時(shí)候會(huì)用“+ =”語(yǔ)法來(lái)調(diào)用它)。這時(shí),反射會(huì)被用來(lái)找到目標(biāo)事件的處理程序的類型。
一旦做到了這點(diǎn),就會(huì)創(chuàng)建一個(gè)Delegate和由這個(gè)MarkupExtension所提供的返回值。在接下來(lái)的例子里面,delegate處理程序是一個(gè)被命名為“MyMarkupExtensionInternalHandler”的方法,定義在標(biāo)記擴(kuò)展本身里。
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget targetProvider = serviceProvider
.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (targetProvider == null)
throw new InvalidOperationException(@"The CallAction extension
can't retrieved the IProvideValueTarget service.");
var targetEventAddMethod = targetProvider.TargetProperty as MethodInfo;
//Retrieve the handler of the event
ParameterInfo[] pars = targetEventAddMethod.GetParameters();
Type delegateType = pars[1].ParameterType;
//Retrieves the method info of the proxy handler
MethodInfo methodInfo = this.GetType()
.GetMethod("MyMarkupExtensionInternalHandler",
BindingFlags.NonPublic | BindingFlags.Instance);
//Create a delegate to the proxy handler on the markupExtension
Delegate returnedDelegate = Delegate
.CreateDelegate(delegateType, this, methodInfo);
return returnedDelegate;
}
void MyMarkupExtensionInternalHandler(object sender, EventArgs e)
{
//here something can be performed.
}
當(dāng)你創(chuàng)建你的標(biāo)記擴(kuò)展的時(shí)候,必須知道的一些事:
1、 當(dāng)有壞的事情發(fā)生了,拋掉 InvalidOperationException,
2、 不要認(rèn)為所有的事情都已經(jīng)初始化了:當(dāng)然不是,特別是對(duì)于目標(biāo)的數(shù)據(jù)文件。
3、 常常檢查你檢索的不為空的對(duì)象,特別是通過(guò) IServiceProvider 參數(shù)而獲得的服務(wù)。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:外文翻譯