轉帖|其它|編輯:郝浩|2011-03-29 15:21:18.000|閱讀 603 次
概述:WPF由于其局限性,目前并不普及,但是其控件模型設計也許是有史以來最優秀的。Silverlight很好的繼承了這一特性,各種模版尤其是 ControlTemplate的引入讓我們很輕易的可以開發出五花八門的控件,但是也正由于它的靈活強大,在基礎類庫中的控件并沒有提供足夠多的屬性和事件來讓我們使用,在很多時候只需要改變一個微小的特性,不得不復制大量ControlTemplate的xaml修改其他的一兩處代碼,然后在繼承類中也做一點小的修改。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
WPF由于其局限性,目前并不普及,但是其控件模型設計也許是有史以來最優秀的。Silverlight很好的繼承了這一特性,各種模版尤其是ControlTemplate的引入讓我們很輕易的可以開發出五花八門的控件,但是也正由于它的靈活強大,在基礎類庫中的控件并沒有提供足夠多的屬性和事件來讓我們使用,在很多時候只需要改變一個微小的特性,不得不復制大量ControlTemplate的xaml修改其他的一兩處代碼,然后在繼承類中也做一點小的修改。
SL有控件有大量和WinForm對應控件相似的屬性,但是和WinForm不一樣,在SL中我們找到了名為XXX屬性之后,很難發現有與之關聯的XXXChanged事件,而這是通過最小的修改量改變現有控件外觀和行為的基礎。還好SL強大的DependencyProperty屬性和Binding類為這一實現提供了可行方法,本文的第一部分我們先實現一個方案,使任何一個DependencyProperty特性的屬性都可以有Changed的事件通知供我們使用,然后利用這一點來實現2個實例:帶有文字說明的DataPager控件和更多控制的ComboBox。
讓一個DataPager帶有一個常見的類似”總計xxx記錄 共xx頁“的文字說明思路很簡單,在OnApplyTemplate中利用GetTemplateChild來取得主要的呈現容器對象(SL4中這是一個水平排列的StackPanel),然后在StackPanel的Children中添加一個TextBlock,接下來要做的就是在DataPager的Source屬性在發生變化的時候更新TextBlock的文本,很自然,我們想到了SourceChanged事件,很不幸的是它并不存在,甚至在派生類中也不能找到OnSourceChanged方法來重寫,在派生類中重寫一個Source來覆蓋父類的Source屬性顯然不是一個好辦法,是的我們僅僅需要的是一個SourceChanged事件而已,而Binding一個DependencyProperty屬性正好可以幫我們達到這一個目的,因為我們綁定一個DependencyProperty之后,被綁定屬性值的變化都可以正確的反應到我們的目標對象。
整個流程已經很清晰了:把Source屬性綁定到一個對象,當Source發生變化時,由于Binding的存在,綁定引擎會把這變化通知到目標對象。就在這個通知過程中,我們利用Binding的Converter來截獲這個新的Source值就可以了。利用這個思路,我們構造一個類來實現這個方案,簡易代碼如下:
1 public partial class DependencyPropertyWatcher
2 {
3
4 TextBlock tb = new TextBlock();
5
6 public void Attach(object source, string property, Action<object> onChange)
{
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath(property),
Source = source,
Converter = new Spyer(onChange)
});
}
}
partial class DependencyPropertyWatcher
{
class Spyer : IValueConverter
{
Action <object> _OnChange;
public Spyer(ActiononChange)
{
_OnChange = onChange;
}
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (_OnChange != null)
{
_OnChange(value);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
<SPAN style="FONT-SIZE: small; FONT-FAMILY: 微軟雅黑" face="微軟雅黑" size="3">這樣,我們可以給任何一個DependencyProperty掛接一個Changed的回調方法。值得注意的是,這個類必須被實例化并被引用,不然tb被GC回收掛接就無效了。</SPAN>
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉載自:博客園