Why does WPF use attached properties for things like positioning in a grid?
Why do we need "attached properties"? The concept of it bugs me a bit, since you can conceivably set values of properties that don't even exist on a particular DependencyObject (and they will just be silently ignored). It almost seems like a solution looking for a problem--why not just do what e.g. HTML does and have the parent element determine things like positioning for children explicitly?
That is, instead of:
<Grid>
<Grid.ColumnDefinitions>
<!-- etc. -->
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- etc. -->
</Grid.RowDefinitions>
<SomeElement Grid.Column="0" Grid.Row="0" />
&l开发者_开发百科t;!-- etc. -->
</Grid>
Why not something like this (the equivalent of <tr>
and <td>
in HTML):
<Grid>
<Grid.Row>
<Grid.Column>
<SomeElement />
</Grid.Column>
<!-- etc. -->
</Grid.Row>
</Grid>
Perhaps grids are just a bad example, and attached properties make more sense in other contexts? Or maybe I'm missing something altogether?
The most obvious reason that you need attached properties to position elements in a grid is so that you can use binding:
<Grid.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</Grid.ItemContainerStyle>
To implement comparable functionality in HTML you have to write code that explicitly removes and re-adds an element when its row and/or column number changes.
Quoting from Programming WPF by Sells and Griffiths: (emphasis mine)
The obvious solution would be for a base class such as
FrameworkElement
to define aDock
property--all WPF user interface elements derive fromFrameworkElement
, so this would enable anything to specify its dock position. However,DockPanel
is not the only panel type, so we would need to add properties for the benefit of other panels, too. This would add a lot of clutter. Worse, it would also be inflexible--what if you want to design a custom panel that implements some new layout mechanism? It might need to define new attributes for its children to use.Attached properties solve this problem. They allow one element to define properties that can be 'attached' to some other element.
DockPanel
defines aDock
property that can be applied to any child. In XAML, the dotted attribute syntax (DockPanel.Dock
) signifies that an attached property is being used
Not really an answer but I for one would argue that the XAML method is easier to read and more intuitive then the HTML Method when dealing with large grids. HTML Tables can be a pain in the butt.
The idea is that controls don't need to know about all possible containers. Without attached properties, UIElement
would need to expose properties specific to each type of container (Row
, Column
, Dock
, Top
, Left
...). This would make the whole system much less flexible, since a new type of container wouldn't easily be able to "add" properties to each control it contains.
If TextBox had properties like Row and Column, it will not make any sense when it is not placed in any Panel directly.
So they are implemented as attached properties. You can "attach" them as per need. If it's in a Panel like DockPanel these attached properties will make sense otherwise they will not.
Hope I cleared some confusion.
精彩评论