2011-03-15 35 views
3

爲什麼我們需要「附加屬性」?它的概念讓我感到有些迷惑,因爲您可以設想設置一些特定的屬性值,這些屬性值甚至不存在於特定的DependencyObject上(並且它們將被忽略)。它幾乎就像是一個尋找問題的解決方案 - 爲什麼不只是做例如HTML確實有父元素來確定像明確定位子項那樣的東西嗎?爲什麼WPF使用附加的屬性來定位網格中的東西?

也就是說,代替:

<Grid> 
    <Grid.ColumnDefinitions> 
    <!-- etc. --> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
    <!-- etc. --> 
    </Grid.RowDefinitions> 
    <SomeElement Grid.Column="0" Grid.Row="0" /> 
    <!-- etc. --> 
</Grid> 

爲什麼不能像這樣(的<tr> HTML中的等價和<td>):

<Grid> 
    <Grid.Row> 
    <Grid.Column> 
     <SomeElement /> 
    </Grid.Column> 
    <!-- etc. --> 
    </Grid.Row> 
</Grid> 

或許電網只是一個壞榜樣,並連接屬性在其他情況下更有意義?或者我可能完全錯過了一些東西?

回答

6

,你需要附加屬性在網格定位元素,最明顯的原因是,你可以使用綁定:

<Grid.ItemContainerStyle> 
    <Style TargetType="ContentPresenter"> 
     <Setter Property="Grid.Row" Value="{Binding Row}"/> 
     <Setter Property="Grid.Column" Value="{Binding Column}"/> 
    </Style> 
</Grid.ItemContainerStyle> 

要在HTML實現類似的功能,你必須編寫代碼來顯式刪除並重新 - 當其行和/或列號改變時添加一個元素。

2

通過塞爾斯和格里菲斯從Programming WPF引用:(重點煤礦)

明顯的解決方案將是一個基類如FrameworkElement以限定Dock屬性 - 所有WPF用戶界面元素從FrameworkElement派生,所以這將使任何事物能夠指定它的碼頭位置。然而,DockPanel不是唯一的面板類型,所以我們需要添加屬性以利於其他面板。 這會增加很多混亂。更糟糕的是,它也不靈活 - 如果你想設計一個自定義面板來實現一些新的佈局機制會怎麼樣?它可能需要爲孩子定義新的屬性。

附加屬性解決了這個問題。它們允許一個元素定義可以附加到其他元素的屬性。 DockPanel定義了可應用於任何孩子的Dock屬性。在XAML中,點屬性語法(DockPanel.Dock)表示,一個附加屬性正在使用

+0

其實,正是這段確切的話讓我問這個問題(我現在正在讀這本書)。注意我沒有建議向FrameworkElement添加屬性;我同意這將是愚蠢的。我想知道爲什麼它沒有像HTML那樣完成 - 也許其原因就像Wegged所說的那樣簡單。 – 2011-03-15 16:58:18

2

不是真的一個一個答案,但我要說的是,XAML方法更容易閱讀,更直觀然後將HTML方法時處理大型電網。 HTML表格可能會讓人感到痛苦。

+0

夠公平! :) – 2011-03-15 16:58:38

2

這個想法是,控件不需要知道所有可能的容器。如果沒有附加屬性,UIElement將需要公開具體到每種類型的容器(,ColumnDockTopLeft ......)的性能。這會使整個系統不夠靈活,因爲新類型的容器不會輕易地將屬性添加到其包含的每個控件中。

+1

爲什麼這個答案沒有引起人們的注意! – Khaliloz 2012-04-27 10:07:29

0

如果文本框有一個像行和列的屬性,它沒有任何意義,當它不直接放置在任何面板英寸

因此,它們被實現爲附加屬性。您可以根據需要「附加」它們。如果它在像DockPanel這樣的面板中,這些附加屬性將有意義,否則它們不會。

希望我澄清了一些混淆。