为什么我们需要“附加属性”?它的概念让我有点烦恼,因为你可以想象设置特定DependencyObject上甚至不存在的属性值(并且它们将被默默地忽略)。它几乎看起来像是一个寻找问题的解决方案 - 为什么不只是做什么,例如HTML确实并且让父元素明确地确定了儿童定位等内容吗?
即代替:
<Grid>
<Grid.ColumnDefinitions>
<!-- etc. -->
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- etc. -->
</Grid.RowDefinitions>
<SomeElement Grid.Column="0" Grid.Row="0" />
<!-- etc. -->
</Grid>
为什么不是这样的(相当于HTML中的<tr>
和<td>
):
<Grid>
<Grid.Row>
<Grid.Column>
<SomeElement />
</Grid.Column>
<!-- etc. -->
</Grid.Row>
</Grid>
也许网格只是一个不好的例子,附加属性在其他环境中更有意义?或者我可能完全错过了一些东西?
答案 0 :(得分:6)
您需要附加属性来定位网格中元素的最明显原因是您可以使用绑定:
<Grid.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</Grid.ItemContainerStyle>
要在HTML中实现类似的功能,您必须编写代码,以便在行和/或列号更改时显式删除和重新添加元素。
答案 1 :(得分:2)
由Sells和Griffiths引自Programming WPF :(强调我的)
显而易见的解决方案是为
FrameworkElement
这样的基类定义Dock
属性 - 所有WPF用户界面元素都派生自FrameworkElement
,这样就可以指定任何内容它的码头位置。但是,DockPanel
不是唯一的面板类型,因此我们还需要为其他面板的好处添加属性。 这会增加很多混乱。更糟糕的是,它也是不灵活的 - 如果你想设计一个实现一些新布局机制的自定义面板怎么办?可能需要为其子项定义新属性。附加属性解决了这个问题。它们允许一个元素定义可以“附加”到其他元素的属性。
DockPanel
定义了可以应用于任何子级的Dock
属性。在XAML中,虚线属性语法(DockPanel.Dock
)表示正在使用附加属性
答案 2 :(得分:2)
不是真正的答案,但我认为XAML方法在处理大型网格时比HTML方法更容易阅读和更直观。 HTML表格可能会很痛苦。
答案 3 :(得分:2)
这个想法是控件不需要知道所有可能的容器。如果没有附加属性,UIElement
将需要公开特定于每种类型容器的属性(Row
,Column
,Dock
,Top
,Left
...)。这会使整个系统的灵活性降低,因为新类型的容器不能轻易地为其包含的每个控件“添加”属性。
答案 4 :(得分:0)
如果TextBox具有“行”和“列”等属性,则当它没有直接放在任何面板中时没有任何意义。
因此它们被实现为附加属性。您可以根据需要“附加”它们。如果它在像DockPanel这样的Panel中,那么这些附加的属性将有意义,否则它们将不会。
希望我清除了一些困惑。