依賴屬性(Dependency Properties)基礎

Windows Presentation Foundation (WPF) 提供了一組服務,這些服務可用於擴展common languageruntime (CLR) 屬性的功能。 這些服務通常統稱爲 WPF 屬性系統。 由 WPF 屬性系統支持的屬性稱爲依賴項屬性。依賴屬性是一種可以自己沒有值,並能通過使用Binding從數據源獲得值的屬性(通俗的講,就是依賴在別的屬性上)。

 

  1. 依賴屬性與CLR屬性

  1. 依賴屬性支持CLR屬性
  2. 依賴項屬性的用途在於提供一種方法來基於其他輸入的值計算屬性值。 這些其他輸入可以包括系統屬性(如主題和用戶首選項)、實時屬性確定機制(如數據綁定和動畫/演示圖板)、重用模板(如資源和樣式)或者通過與元素樹中其他元素的父子關係來公開的值。 另外,可以通過實現依賴項屬性來提供獨立驗證、默認值、監視其他屬性的更改的回調以及可以基於可能的運行時信息來強制指定屬性值的系統。 派生類還可以通過重寫依賴項屬性元數據(而不是重寫現有屬性的實際實現或者創建新屬性)來更改現有屬性的某些具體特徵。
  3. 如何區分依賴屬性與CLR屬性:在屬性的MSDN幫助文檔中,假如該屬性爲依賴屬性,在屬性說明中會有依賴項屬性信息說明,如下(TextBox.Text):
  1. 定義依賴屬性

例子:書寫MyTextBox控件,繼承自TextBox。給MyTextBox添加MyText依賴屬性:

        

	//依賴屬性名稱MyTextProperty
        //依賴屬性標識符MyText
        public static readonly DependencyProperty MyTextProperty =
            DependencyProperty.Register("MyText", typeof(string), typeof(MyTextBox));
 
        //依賴屬性的CLR屬性包裝
        public string MyText
        {
            get { return (string)GetValue(MyTextProperty); }
            set { SetValue(MyTextProperty, value); }
        }

Register 方法 參數說明

name

要註冊的依賴項對象的名稱。

propertyType

屬性的類型。

ownerType

正註冊依賴項對象的所有者類型。

typeMetadata

依賴項對象的屬性元數據。

validateValueCallback

對回調的引用,除了典型的類型驗證之外,該引用還應執行依賴項對象值的任何自定義驗證。

 

 

  1. 依賴屬性提供的屬性功能

  1. 資源

依賴項屬性值可以通過引用資源來設置。

    

    <Window.Resources>
        <!--資源-->
        <sys:String x:Key="text">text_Resources</sys:String>
    </Window.Resources>
    <Grid>
        <!--Text屬性引用資源-->
        <MyTextBox:MyTextBox x:Name="myTextBox" HorizontalAlignment="Left" Height="44" Margin="70,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="213"
                             Text="{DynamicResource text}"/>
    </Grid>

  1. 數據綁定

綁定注意點:(1) 綁定必須指定數據上下文DataContext;

  (2)綁定源必須是屬性,變量無效;

  (3)綁定源必須是公開的Public;

  (4)如果綁定源更改時,控件綁定目標依賴屬性需要跟隨更改,那麼綁定源必須繼承INotifyPropertyChanged接口。

示例(TextBox.Text依賴屬性綁定到MainWindow類中的TextForBinding屬性):

        public string TextForBinding { get; set; }

繼承INotifyPropertyChanged接口的寫法:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public string TextForBinding { get; set; }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        private void OnPropertyChanged(string info)
        {
            PropertyChangedEventHandler handler =PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(info));
            }
        }
    }

XAML中:

Text="{Binding TextForBinding}"

  1. 樣式

示例(寫一個紅色前景色的樣式並引用):

書寫樣式:

    <Window.Resources>
        <!--資源-->
        <sys:String x:Key="text">text_Resources</sys:String>
       
        <Style x:Key="MyStyle" TargetType="MyTextBox:MyTextBox">
            <Setter Property="Foreground" Value="Red" />
        </Style>
</Window.Resources>

引用樣式

Style="{DynamicResource MyStyle}"

  1. 動畫

示例(鼠標進入文本框時文本框變寬):

        <MyTextBox:MyTextBox x:Name="myTextBox" HorizontalAlignment="Left" Height="44" Margin="70,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="213"
                             Text="{Binding TextForBinding}"
                             Style="{DynamicResource MyStyle}">
            <MyTextBox:MyTextBox.Triggers>
                <EventTrigger RoutedEvent="TextBox.MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="myTextBox"
                                Storyboard.TargetProperty="Width"
                                By="100" Duration="0:0:2"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </MyTextBox:MyTextBox.Triggers>
        </MyTextBox:MyTextBox>

鼠標離開時的沒寫,大家可以自己寫下。

  1. 元數據重寫

在依賴屬性進階中說明。

  1. 屬性值繼承

元素可以從其在對象樹中的父級繼承依賴項屬性的值。

在功能2的數據綁定中,給窗體綁定數據上下文DataContext,代碼如下:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
 
            TextForBinding = "TextForBinding";
 
            this.DataContext = this;
        }
 
        …
    }

子對象(MyTextBox)中的爲指定數據上下文即可進行數據綁定。

  1. WPF設計器集成

自定義控件具有實現爲依賴項屬性的屬性,則它將收到相應的適用於 Visual Studio 的 WPF 設計器支持。

<MyTextBox:MyTextBox x:Name="myTextBox" MyText="WPF 設計器集成"/>

  1. 依賴屬性優先級

最高優先級將最先列出,順序如下:

  1. 屬性系統強制轉換。
  2. 活動動畫或具有 Hold 行爲的動畫。爲了獲得任何實用效果,屬性的動畫必須優先於基(未動畫)值,即使該值是在本地設置的情況下也將如此。 
  3. 本地值。本地值可以通過“包裝”屬性的便利性進行設置,這也相當於在 XAML 中設置特性或屬性元素,或者使用特定實例的屬性調用 SetValueAPI。 如果您使用綁定或資源來設置本地值,則每個值都按照直接設置值的優先級順序來應用。
  4. TemplatedParent 模板屬性。如果元素是作爲模板(ControlTemplate  DataTemplate)的一部分創建的,則具有TemplatedParent。 在模板中,按以下優先級順序應用:
    1. 來自TemplatedParent 模板的觸發器。
    2. TemplatedParent 模板中的屬性集。(通常通過 XAML特性進行設置。)
  5. 隱式樣式。僅應用於 Style 屬性。 Style 屬性是由任何樣式資源通過與其類型匹配的鍵來填充的。 該樣式資源必須存在於頁面或應用程序中;查找隱式樣式資源不會進入到主題中。
  6. 樣式觸發器。來自頁面或應用程序上的樣式中的觸發器。(這些樣式可以是顯式或隱式樣式,但不是來自優先級較低的默認樣式。)
  7. 模板觸發器。來自樣式中的模板或者直接應用的模板的任何觸發器。
  8. 樣式 Setter。來自頁面或應用程序的樣式中的Setter的值。
  9. 默認(主題)樣式。 在默認樣式中,按以下優先級順序應用:
    1. 主題樣式中的活動觸發器。
    2. 主題樣式中的 Setter
  10. 繼承。有幾個依賴項屬性從父元素向子元素繼承值,因此不需要在應用程序中的每個元素上專門設置這些屬性。
  11. 來自依賴項屬性元數據的默認值。任何給定的依賴項屬性都具有一個默認值,它由該特定屬性的屬性系統註冊來確定。 而且,繼承依賴項屬性的派生類具有按照類型重寫該元數據(包括默認值)的選項。 因爲繼承是在默認值之前檢查的,所以對於繼承的屬性,父元素的默認值優先於子元素。 因此,如果任何地方都沒有設置可繼承的屬性,將使用在根元素或父元素中指定的默認值,而不是子元素的默認值。

 

代碼

參考內容:http://msdn.microsoft.com/zh-cn/library/ms752914(v=vs.100).aspx


作者:FoolRabbit
出處:http://blog.csdn.net/rabbitsoft_1987
歡迎任何形式的轉載,未經作者同意,請保留此段聲明!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章