1,前幾天學習一個專案的時候,遇到了PasswordBox這個控制元件,由於這個控制元件的Password屬性,不是依賴屬性,所以不能和ViewModel層進行資料繫結。
2,但是要實現前後端徹底的分離,就需要繫結,那麼下面我的本文的主角“附加屬性”就要出場了。
3,附加屬性的概念,就是類(控制元件類)本身沒有這個屬性,我們給它一個我們定義的屬性。那是怎麼給的呢?
4,怎麼給的,剛開始我也很迷惑,其實就是在xmal檔案中,在控制元件屬性中,直接寫上我們定義的附加屬性就好(放心,編輯器是不會報錯的)。
5,附加屬性,是一個屬性,屬性必須依附於類,也就是我們要來定義一個類,來容納我們的附加屬性。
要定義一個附加屬性,需要這麼多的程式碼,別擔心,這些程式碼不需要您手動敲出來,在vs的類中,找一個合適的地方,輸入“propa”,然後根據編輯器的提示,按兩次Tab鍵,
編輯器會自動幫助您完成這些程式碼。然後再次按Tab鍵,編輯器會引導您做“完形填空”(不會完型填空的朋友,您可以查下資料,本文不再贅述),直到您按下Enter鍵,這個附加屬性就建立完成了。
(此處的CallBack方法,是我自己定義的,不是自動生成的。什麼?你說我為什麼知道CallBack的引數是DependencyObject和DependencyPropertyChangedEventArgs,為什麼知道CallBack可以放到
PropertyMetadata的建構函式中,因為我查從源資料了啊 ^-^ ^-^,檢視下PropertyMetadata的定義就知道了(使用方法後面講)。
注意,注意,注意(重要的話說三遍,否則你的下一步將無法進行!!!)
上面定義的類,它的檔案位置在這裡:
7,附加屬性定義好了,怎麼來使用它呢?也是一個問題,我到現在還是沒有完全扭轉過來這個思維,慚愧!!!下面講一下怎麼來使用它:
在窗體中,定義一個Rectangle,在Rectangle的屬性中,寫上我們定義的附加屬性,大膽寫,儘管寫,不會出錯的。
因為我們定義的類,存在於名稱空間WpfTest中,而WpfTest在xaml對映在local,因此我們的附加屬性Height存在於local:AttachProperty.Height,
第一次使用這個附加屬性的時候,編輯器會報錯,提示“名稱空間clr-namespace:WpfTest中不存在AttachProperty名稱”,
如果確定檔案位置是對的,先不用管這句話,執行之後,就不會再報錯了,為什麼會這樣,請路過的大神,幫忙指點一二,非常感激。
8,來到主窗體的建構函式內,寫下這句話:
然後啟動窗體,可以看到,窗體內矩形的高,由xaml中設定的50變成了我們在構造器中設定的100,那麼就是說這個附加屬性對於描繪矩形起效了(注意再xaml中是雙向繫結)。
9,附加屬性的獲取:在主窗體的建構函式中,寫下這樣的程式碼:
然後啟動,就可以看到MessageBox中,會顯示您在xmal中這是的rectangle的高的值,為50.
後記:1,在第五步中,我們定義了一個附加屬性,並且定義了一個CallBack委託,當值發生變化的時候,我們在委託方法中,就可以去到附加屬性的值,可以在這裡編寫我們的業務邏輯。
2,全篇文章看下來,和PassowrdBox完全沒有關係對吧?因為它不是本文的重點,下面簡述一下。
3,PasswordBox的Password屬性,不是依賴屬性,那麼我們就給他一個附加屬性,在CallBack中,獲取到PasswordBox的例項,指定PasswordBox的PasswordChanged事件處理程式,
在事件處理程式中,可以對model進行繫結,注意,在為PasswordBox建立附加屬性時,要指定一個string型別的預設值,用於觸發PasswordChanged事件處理程式的執行。
4,附加屬性的設定,對於控制元件來說,不會起任何視覺上的效果,我們還必須要在viewModel層,對拿到的附加屬性值進行處理,來使控制元件的視覺效果發生變化。