WPF入门教程(七)---依赖属性(3)(转)
WPF入門教程(七)---依賴屬性(3)
2018年08月24日 08:33:43?weixin_38029882?閱讀數(shù):50四、 只讀依賴屬性
在以前在對于非WPF的功能來說,對于類的屬性的封裝中,經(jīng)常會對那些希望暴露給外界只讀操作的字段封裝成只讀屬性,同樣在WPF中也提供了只讀屬性的概念,如一些 WPF控件的依賴屬性是只讀的,它們經(jīng)常用于報告控件的狀態(tài)和信息,像IsMouseOver等屬性, 那么在這個時候?qū)λx值就沒有意義了。 或許你也會有這樣的疑問:為什么不使用一般的.Net屬性提供出來呢?一般的屬性也可以綁定到元素上呀?這個是由于有些地方必須要用到只讀依賴屬性,比如 Trigger等,同時也因為內(nèi)部可能有多個提供者修改其值,所以用.Net屬性就不能完成天之大任了。?
那么一個只讀依賴屬性怎么創(chuàng)建呢?其實創(chuàng)建一個只讀的依賴屬性和創(chuàng)建一個一般的依賴屬性大同小異。不同的地方就是DependencyProperty.Register變成了DependencyProperty.RegisterReadOnly。和前面的普通依賴屬性一樣,它將返回一個 DependencyPropertyKey。而且只提供一個GetValue給外部,這樣便可以像一般屬性一樣使用了,只是不能在外部設(shè)置它的值罷了。?
下面我們就用一個簡單的例子來概括一下:
?
XMAL代碼
<Window x:Name="winReadOnly" x:Class="WpfApp1.WindowReadOnly" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WindowDepend" Height="300" Width="300"> <Grid> <Viewbox> <TextBlock Text="{Binding ElementName=winReadOnly, Path=Counter}" /> </Viewbox> </Grid> </Window>五、附加屬性
現(xiàn)在我們再繼續(xù)探討另外一種特殊的依賴屬性——附加屬性。附加屬性是一種特殊的依賴屬性。這是WPF的特性之一,通俗的理解起來就是,別人有的屬性,由于你跟他產(chǎn)生了關(guān)系所以你也有了這個屬于他的屬性。?
附加屬性是說一個屬性本來不屬于某個對象,但由于某種需求而被后來附加上,也就是把對象放入一個特定環(huán)境后對象才具有的屬性就稱為附加屬性,附加屬性的作 用就是將屬性與數(shù)據(jù)類型解耦,讓數(shù)據(jù)類型的設(shè)計更加靈活,舉例,一個TextBox被放在不同的布局容器中時就會有不同的布局屬性,這些屬性就是由布局容 器為TextBox附加上的,附加屬性的本質(zhì)就是依賴屬性,二者僅僅在注冊和包裝器上有一點區(qū)別。?
附加屬性是依賴屬性的一種特殊形式,它可以讓用戶在一個元素中設(shè)置其他元素的屬性。一般來說,附加屬性是用于一個父元素定位其他元素布局 的。就像Grid和DockPanel元素就包含附加屬性。Grid使用附加屬性來指定包含子元素的特定行和列,而DockPanel使用附加屬性是來指 定子元素應(yīng)該停靠在面板中的何處位置。?
附加屬性就是自己沒有這個屬性,在某些上下文中需要就被附加上去。比如StackPanel的Grid.Row屬性,如果我們定義StackPanel類時定義一個Row屬性是沒有意義的,因為我們并不知道一定會放在Grid里,這樣就造成了浪費。?
例如,下面轉(zhuǎn)場控件的定義使用了Grid的Row屬性來將自身定位到特定的行中。
?
盡管對于一個普通的WPF開發(fā)人員來說,理解依賴和附加屬性并不一定是必須的,但是掌握好WPF系統(tǒng)的整個運行機制對于提升WPF應(yīng)用技術(shù)是非常重要的。?
使用附加屬性,可以避開可能會防止一個關(guān)系中的不同對象在運行時相互傳遞信息的編碼約定。一定可以針對常見的基類設(shè)置屬性,以便每個對象只需獲取和 設(shè)置該屬性即可。但是,你可能希望在很多情況下這樣做,這會使你的基類最終充斥著大量可共享的屬性。它甚至可能會引入以下情況:在數(shù)百個后代中,只有兩個 后代嘗試使用一個屬性。這樣的類設(shè)計很糟糕。為了解決此問題,我們使用附加屬性概念來允許對象為不是由它自己的類結(jié)構(gòu)定義的屬性賦值。在創(chuàng)建對象樹中的各 個相關(guān)對象之后,在運行時從子對象讀取此值。?
最好的例子就是布局面板。每一個布局面板都需要自己特有的方式來組織它的子元素。如Canvas需要Top和left來布 局,DockPanel需要Dock來布局。當然你也可以寫自己的布局面板(在上一篇文章中我們對布局進行了比較細致的探討,如果有不清楚的朋友也可以再 回顧一下)。?
下面代碼中的Button 就是用了Canvas的Canvas.Top和Canvas.Left=”20” 來進行布局定位,那么這兩個就是傳說中的附加屬性。
定義附加屬性的方法與定義依賴屬性的方法一致,前面我們是使用DependencyProperty.Register來注冊一個依賴屬性,只是在注冊屬性時使用的是RegisterAttach()方法。這個RegisterAttached的參數(shù)和 Register是完全一致的,那么Attached(附加)這個概念又從何而來呢??
其實我們使用依賴屬性,一直在Attached(附加)。我們注冊(構(gòu)造)一個依賴屬性,然后在DependencyObject中通過 GetValue和SetValue來操作這個依賴屬性,也就是把這個依賴屬性通過這樣的方法關(guān)聯(lián)到了這個DependencyObject上,只不過是 通過封裝CLR屬性來達到的。那么RegisterAttached又是怎樣的呢??
下面我們來看一個最簡單的應(yīng)用:首先我們注冊(構(gòu)造)一個附加屬性
然后,我們在程序中使用這個我們自己定義的附加屬性?
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfApp1.Services"Title="WindowTurnover" Height="400" Width="500" Loaded="Window_Loaded"><Grid><Grid.RowDefinitions><RowDefinition Height="313*"/><RowDefinition Height="57*"/></Grid.RowDefinitions><Canvas Grid.Row="0"><Ellipse Name="ellipseRed" Fill="Red" Width="100" Height="60" Canvas.Left="56"Canvas.Top="98" local:TurnoverManager.Angle="{Binding ElementName=sliderAngle, Path=Value}"/><Rectangle Name="ellipseBlue" Fill="Blue" Width="80" Height="80" Canvas.Left="285"Canvas.Top="171" local:TurnoverManager.Angle="45" /><Button Name="btnWelcome" Content="歡迎光臨" Canvas.Left="265" Canvas.Top="48" FontSize="20" local:TurnoverManager.Angle="60"/></Canvas><WrapPanel Grid.Row="1"><Label Content="角度大小" /><Slider x:Name="sliderAngle" Minimum="0" Maximum="240" Width="300" /></WrapPanel></Grid>?
?
在XAML中就可以使用剛才注冊(構(gòu)造)的附加屬性了:如下圖。?
?
效果如圖所示?
轉(zhuǎn)載于:https://www.cnblogs.com/LiZhongZhongY/p/10870137.html
總結(jié)
以上是生活随笔為你收集整理的WPF入门教程(七)---依赖属性(3)(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电气图图形符号
- 下一篇: IDEA 快捷键MacOS