日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

4 WPF依赖属性

發(fā)布時間:2023/12/9 asp.net 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 4 WPF依赖属性 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

理解依賴屬性

依賴屬性支持的特征包括:動畫、數(shù)據(jù)綁定、樣式。由WPF元素暴露的屬性大部分都是依賴屬性。依賴屬性和常規(guī)屬性的使用方法相同。

WPF設(shè)計了依賴屬性支持其特有的動態(tài)特性,并且不干擾其他系統(tǒng)的.net代碼。

定義依賴屬性

創(chuàng)造一個依賴屬性的語法完全不同于創(chuàng)造一個普通的.NET屬性。

第一步是定義一個代表屬性的對象。這是DependencyProperty類的一個實例。關(guān)于你屬性的信息需要一直是可用的,甚至可能在類之間共享(常見在WPF元素中)。因此,你的DependencyProperty對象必須被定義為相關(guān)類的一個靜態(tài)字段。

例如,FrameworkElement類定義了一個Margin屬性。Margin被所有元素共享,是一個依賴屬性:

public class FrameworkElement: UIElement, ... {public static readonly DependencyProperty MarginProperty;... }

根據(jù)命名約定,定義依賴屬性的字段名字是正常屬性加上單詞Property后綴。那樣,你能區(qū)分依賴屬性定義和實際屬性的名字。字段使用readonly關(guān)鍵字,這意味著它只能在FrameworkElement類的靜態(tài)構(gòu)造函數(shù)中設(shè)置,如何設(shè)置見下節(jié)。

注冊依賴屬性

下一步是注冊你的依賴屬性。因為要在使用屬性之前完成注冊,必須在相關(guān)類的一個靜態(tài)構(gòu)造函數(shù)中執(zhí)行它。

不能直接實例化DependencyProperty對象,因為DependencyProperty類沒有公開的構(gòu)造函數(shù)。代替,一個DependencyObject實例只能使用靜態(tài)的DependencyProperty.Register()方法被創(chuàng)造。DependencyProperty對象被創(chuàng)造之后不能再修改,因為所有的DependencyProperty成員是只讀的。代替,它們的值必須作為Register()方法的參數(shù)被提供。

下面例子顯示FrameworkElement類的Margin屬性是如何被注冊的:

static FrameworkElement() {var metadata = new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);MarginProperty = DependencyProperty.Register("Margin",typeof(Thickness), typeof(FrameworkElement), metadata,new ValidateValueCallback(FrameworkElement.IsMarginValid));... }

注冊一個依賴屬性包括二步。首先,你創(chuàng)造一個FrameworkPropertyMetadata對象,指明希望使用依賴屬性的什么服務(wù)(諸如支持?jǐn)?shù)據(jù)綁定,動畫,和日志)。其次,依靠調(diào)用DependencyProperty.Register()靜態(tài)方法注冊屬性。這時,你負(fù)責(zé)提供一些關(guān)鍵成分:

  • 屬性名稱
  • 屬性的數(shù)據(jù)類型
  • 屬性所在類的類型
  • 可選,附帶有屬性設(shè)置的FrameworkPropertyMetadata對象
  • 可選,執(zhí)行屬性驗證的回調(diào)

兩個可選屬性值得研究。FrameworkPropertyMetadata的詳細(xì)描述見95頁。

包裝依賴屬性

創(chuàng)造依賴屬性的最后一步是用一個傳統(tǒng).NET屬性包裝它。WPF屬性使用的是定義在DependencyObject基類的GetValue()和SetValue()方法。

public Thickness Margin {set { SetValue(MarginProperty, value); }get { return (Thickness)GetValue(MarginProperty); } }

當(dāng)你創(chuàng)造屬性包裝時,你應(yīng)該僅調(diào)用SetValue()和GetValue(),如在前例中。你不應(yīng)該添加任何額外的代碼驗證值,引起事件,等等。那是因為另外的特征可能旁路屬性包裝,直接調(diào)用SetValue()和GetValue()。(一個例子是在運行時當(dāng)一個編譯XAML文件被解析時。)SetValue()和GetValue()都是公開的。

驗證輸入值應(yīng)使用DependencyProperty.ValidateValueCallback。

引發(fā)事件應(yīng)使用FrameworkPropertyMetadata.PropertyChangedCallback 。

現(xiàn)在可以使用屬性了:

myElement.Margin = new Thickness(5);

之后,可能希望移除局部值設(shè)置,仿佛你從未設(shè)置它。依靠從DependencyObject繼承的ClearValue()方法。

myElement.ClearValue(FrameworkElement.MarginProperty);

使用依賴屬性

依賴屬性支持兩個關(guān)鍵的行為:改變通知和動態(tài)值求解。

改變通知

如果你希望對一個屬性的改變作出反應(yīng),你有二個選擇—創(chuàng)造一個綁定,或?qū)懸粋€觸發(fā)器。但是,依賴屬性沒有提供響應(yīng)屬性值改變的事件。

動態(tài)值求解

依賴屬性因動態(tài)值求解的行為而得名。一個依賴屬性依賴于多個屬性提供者,每個提供者帶有它自己的優(yōu)先級。當(dāng)你從一個屬性值取回一個值時,WPF屬性系統(tǒng)經(jīng)歷一系列步驟求得最終值。首先,它通過考慮下列因素決定屬性的基值。優(yōu)先級從最低的到最高排列(最下面的贏):

  • 默認(rèn)值(由FrameworkPropertyMetadata對象設(shè)置)
  • 繼承的值(如果FrameworkPropertyMetadata.Inherits標(biāo)記被設(shè)置,并且一個值已經(jīng)應(yīng)用到某個祖先元素)
  • 主題樣式值
  • 工程樣式值
  • 本地值(使用代碼或標(biāo)記直接設(shè)置的值)
  • 基值不一定是最終的屬性值,WPF通過4個步驟求得屬性值:

  • 基值
  • 表達(dá)式(數(shù)據(jù)綁定和資源)
  • 動畫
  • 通過CoerceValueCallback修正值
  • 共享依賴屬性

    一些類共享依賴屬性,即使他們有獨立的類層次結(jié)構(gòu)。例如,TextBlock.FontFamily和Control.FontFamily都指向同一個依賴屬性,它實際上被定義在TextElement類中以及TextElement.FontFamilyProperty。TextElement類的靜態(tài)構(gòu)造函數(shù)注冊屬性,但是TextBlock和Control類的靜態(tài)構(gòu)造函數(shù)簡單地調(diào)用DependencyProperty.AddOwner()方法重用它:

    TextBlock.FontFamilyProperty =TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));

    自定義類

    副作用

    附加依賴屬性

    附加屬性是依賴屬性,并且它被WPF屬性系統(tǒng)管理。區(qū)別是應(yīng)用附加屬性的類不是定義它的類。

    為定義一個附加屬性,你使用RegisterAttached()方法而不是Register()。這是一個注冊Grid.Row屬性的例子:

    var metadata = new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged));Grid.RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int),typeof(Grid), metadata, new ValidateValueCallback(Grid.IsIntValueNotNegative));

    就像一個普通的依賴屬性,你能提供一個FrameworkPropertyMetadata對象和一個ValidateValueCallback。

    當(dāng)創(chuàng)造附加屬性時,你沒有定義.NET屬性包裝。那是因為附加屬性能被設(shè)置在任何依賴對象上。例如,Grid.Row屬性可能被設(shè)置在一個Grid對象上(如果你有一內(nèi)部嵌套另一個Grid的Grid)或在另外的一些元素上。事實上,即使元素不在一個Grid內(nèi),和即使在你的元素樹上不存在Grid對象,Grid.Row屬性也能被設(shè)置在那個元素上。

    代替使用一個.NET屬性包裝,附加屬性要求能調(diào)用的一對靜態(tài)方法去設(shè)置和獲得屬性值。這些方法使用熟悉的SetValue()和GetValue()方法(從DependencyObject類繼承)。靜態(tài)的方法應(yīng)該被命名SetPropertyName()和GetPropertyName()。

    這里是實現(xiàn)Grid.Row附加屬性的靜態(tài)方法:

    public static int GetRow(UIElement element) {if (element == null){throw new ArgumentNullException("");}return (int)element.GetValue(Grid.RowProperty); } public static void SetRow(UIElement element, int value) {if (element == null){throw new ArgumentNullException("");}element.SetValue(Grid.RowProperty, value); }

    使用代碼設(shè)置一個元素位于網(wǎng)格的第一行:

    Grid.SetRow(txtElement, 0);

    可選地,你能直接調(diào)用SetValue()或GetValue()方法,旁路掉靜態(tài)方法:

    txtElement.SetValue(Grid.RowProperty, 0);

    屬性驗證

    WPF提供兩種方法阻止無效值:

    • ValidateValueCallback:這回調(diào)能接受或拒絕新值。通常,這回調(diào)被用來捕獲違反屬性的約束明顯錯誤。提供它作為DependencyProperty.Register()方法的參數(shù)。
    • CoerceValueCallback:這回調(diào)能修改新值為更可接受的值。通常,這回調(diào)被用來處理被設(shè)置在同一對象的依賴屬性值之間的沖突。這些值可能單獨是有效的,但是當(dāng)應(yīng)用在一起時不一致。為使用這回調(diào),當(dāng)創(chuàng)造FrameworkPropertyMetadata對象時,提供它作為構(gòu)造函數(shù)的參數(shù),此對象隨后被傳遞到DependencyProperty.Register()方法。

    這里是當(dāng)應(yīng)用程序試圖設(shè)置一個依賴屬性時:所有的部件如何起作用:

  • 首先,CoerceValueCallback方法有機會修改提供值(通常,為使它與其它屬性一致)或返回DependencyProperty.UnsetValue,這完全拒絕改變。
  • 其次,ValidateValueCallback被引發(fā)。這方法返回真接受一個值作為有效,或返回假拒絕它。不同于CoerceValueCallback,ValidateValueCallback不訪問設(shè)置屬性的實際對象,這意味著你不能檢查其它的屬性值。
  • 最后,如果先前兩個階段都成功了,PropertyChangedCallback被觸發(fā)。這時,你能引發(fā)事件去通知其它類。
  • Validation回調(diào)

    相當(dāng)于正常屬性的set部分中的驗證。

    其簽名為接受一個object輸入?yún)?shù),返回布爾值。返回值為真表示接受,為假表示拒絕。

    private static bool IsMarginValid(object value) {Thickness thickness1 = (Thickness) value;return thickness1.IsValid(true, false, true, false); }

    有一個限制,它是一個靜態(tài)方法,不能訪問正被驗證的對象,不能使用對象中的其他屬性。

    Coercion回調(diào)

    用于驗證互相關(guān)聯(lián)的屬性

    private static object CoerceMaximum(DependencyObject d, object value) {RangeBase base1 = (RangeBase)d;if (((double) value) < base1.Minimum){return base1.Minimum;}return value; }

    轉(zhuǎn)載于:https://www.cnblogs.com/cuishengli/archive/2013/06/01/3112538.html

    總結(jié)

    以上是生活随笔為你收集整理的4 WPF依赖属性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。