Silverlight:Dependency Property(依賴屬性)學習筆記

學習SL/WPF,Dependency Properties(依賴屬性)是一個全新(陌生)但又無法迴避的概念。

http://www.wpftutorial.net/DependencyProperties.html 這裏有一篇通俗易懂的相關文章,不過是E文的,E文不好的朋友,也可以參考下面的內容:

1.爲什麼會出現依賴屬性?

先回想一下傳統的屬性(Property):通常我們讀取或賦值一個屬性時,實際上是在對屬性背後的某個私有成員進行讀寫。那麼隨着對象的屬性越來越多,再加上從對象派生出去的子對象,子對象再生出“孫子”對象......最終的對象運行實例中會有大量的私有成員,而每私有成員都要分配內存,佔用一定的資源。

但反過來想想,通常我們在使用一個控件/對象時,往往只用到了某幾個屬性,大部分屬性(有時候甚至達到90%以上)都是採用的默認值(或者也可以理解爲沒有用到),這對於WPF/SL來說無疑是一種極大的性能損耗。

所以在此背景之下,DP(Dependency Properties的簡稱)就出現了,我們再回想一下靜態(static)方法或成員,靜態成員/方法的調用不依賴於實例,它是class級別的,不管這個類有多少個實例,靜態成員在內存中只佔一份,這正是我們所要的!

2.依賴屬性的大致原理及好處

所有具備依賴屬性的對象,都是繼承自DependencyObject,DependencyObject中有一個"字典"存儲區用來存放依賴屬性,而且都是用static方式讀取的,所以你現在應該想明白了:爲啥不能直接用txt.Left = xxx來直接賦值,而必須用txt.SetValue(Canvas.Left,xxx)來處理,因爲static成員是實例無法調用的。

DP的優點:
(1)有效降低內存消耗。
(2)直接繼承上級的屬性值(這裏也解釋了爲什麼上級控件對下級控件自動佈局,因爲下級控件自動繼承了上級控件的相關屬性值)
(3)自動實現了“變化通知”(dp有內置的Change Notification回調接口)

3.依賴屬性值的讀取策略



這張圖描述了GetValue與SetValue的內部讀取策略.

4.依賴屬性的使用示例:

下面我們演示如何給一個用戶自定義控件添加Message依賴屬性

(1)先建一個Silverlight User Control,取名爲MyControl
xaml部分:
代碼
<UserControl x:Class="DPStudy.MyControl"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml" 
    
>
    
<Border CornerRadius="5" BorderThickness="3" BorderBrush="#FFEF410D" Width="300" Height="40" Margin="5"  >        
        
<TextBlock x:Name="txt" Text="" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
    
</Border>
</UserControl>

CS部分:(技巧:vs2008中,只要鍵入propdp,再連敲二次Tab鍵,vs就會自動添加一個依賴屬性的代碼模板)

代碼
using System.Windows;
using System.Windows.Controls;


namespace DPStudy
{
    
public partial class MyControl : UserControl
    {
            
        
        
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message"typeof(string), typeof(MyControl), new PropertyMetadata("Message的默認值"new PropertyChangedCallback(OnMessagePropertyChanged)));

        
public string Message
        {
            
get { return (string)GetValue(MessageProperty); }
            
set { SetValue(MessageProperty, value); }
        }

        
/// <summary>
        
/// Message變化時的通知處理
        
/// </summary>
        
/// <param name="d"></param>
        
/// <param name="e"></param>
        private static void OnMessagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MyControl ctl 
= d as MyControl;
            ctl.txt.Text 
= d.GetValue(MyControl.MessageProperty).ToString();
        }      


        
public MyControl()
        {
            InitializeComponent();

            
this.Loaded += new RoutedEventHandler(MyControl_Loaded);
        }

        
void MyControl_Loaded(object sender, RoutedEventArgs e)
        {
            
this.txt.Text = Message;//初始加載時,顯示Message的初始值
        }
    }
}

這裏我們定義了一個Message的string類型依賴屬性,和普通屬性的區別是:必須使用DependencyProperty.Register來註冊該屬性,而且“屬性命名”要以Property爲後綴;另外在讀取時,必須調用SetValue/GetValue靜態方法來讀取其值,最後我們還可以添加一個"屬性值變化時的"回調處理。

(2)將MyControl放到MainPage.xaml中小試牛刀
MainPage.Xaml內容如下:

代碼
<UserControl x:Class="DPStudy.MainPage"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             
xmlns:l="clr-namespace:DPStudy"
    mc:Ignorable
="d" d:DesignWidth="640" d:DesignHeight="480">
  
<StackPanel x:Name="LayoutRoot">        
        
<l:MyControl x:Name="myctl"></l:MyControl>
        
<Button Click="Button_Click" Content="改變Message屬性值" Width="130" ></Button>
    
</StackPanel>
</UserControl>

 

MainPage.Xaml.cs內容如下:

代碼
using System.Windows;
using System.Windows.Controls;

namespace DPStudy
{
    
public partial class MainPage : UserControl
    {
        
public MainPage()
        {
            InitializeComponent();            
        }

       
        
private void Button_Click(object sender, RoutedEventArgs e)
        {
            myctl.SetValue(MyControl.MessageProperty, 
"新值");
        }
    }
}

運行後,點擊按鈕將改變MyControl控件的Message屬性值,同時MyControl中的文本控件的文字也將變成"新值"

轉載請註明來自菩提樹下的楊過

文中源文件代碼:DPStudy.rar
作者:菩提樹下的楊過
出處:http://yjmyzz.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章