3

为什么我们需要“附加属性”?它的概念让我有点困惑,因为您可以想象设置特定 DependencyObject 上甚至不存在的属性的值(它们将被默默地忽略)。这似乎是一个寻找问题的解决方案——为什么不只做 HTML 所做的事情,让父元素明确地确定子元素的定位?

也就是说,而不是:

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

为什么不这样(相当于HTML中的<tr>and ):<td>

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

也许网格只是一个不好的例子,附加属性在其他情况下更有意义?或者也许我完全错过了一些东西?

4

5 回答 5

6

您需要附加属性来定位网格中的元素的最明显原因是您可以使用绑定:

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

要在 HTML 中实现类似的功能,您必须编写代码,在元素的行号和/或列号更改时显式删除和重新添加元素。

于 2011-03-15T16:58:45.673 回答
2

不是一个真正的答案,但我认为在处理大型网格时,XAML 方法比 HTML 方法更容易阅读和更直观。HTML 表格可能会让人头疼。

于 2011-03-15T16:51:08.683 回答
2

Sells 和 Griffiths从Programming WPF中引用:(强调我的)

显而易见的解决方案是为基类FrameworkElement定义一个Dock属性——所有 WPF 用户界面元素都派生自FrameworkElement,因此这将使任何东西都可以指定其停靠位置。但是,DockPanel它不是唯一的面板类型,因此我们也需要添加属性以使其他面板受益。这会增加很多混乱。更糟糕的是,它也很不灵活——如果你想设计一个自定义面板来实现一些新的布局机制怎么办?它可能需要定义新的属性供其子级使用。

附加属性解决了这个问题。它们允许一个元素定义可以“附加”到其他元素的属性。DockPanel定义一个Dock可以应用于任何孩子的属性。在 XAML 中,点属性语法 ( DockPanel.Dock) 表示正在使用附加属性

于 2011-03-15T16:48:43.757 回答
2

这个想法是控件不需要知道所有可能的容器。如果没有附加属性,UIElement则需要公开特定于每种容器类型的属性(Row, Column, Dock, Top, Left...)。这将使整个系统的灵活性大大降低,因为一种新型容器不能轻易地向它包含的每个控件“添加”属性。

于 2011-03-15T17:05:59.170 回答
0

如果 TextBox 有 Row 和 Column 之类的属性,那么当它不直接放在任何 Panel 中时,它就没有任何意义。

因此它们被实现为附加属性。您可以根据需要“附加”它们。如果它在像 DockPanel 这样的面板中,这些附加属性将有意义,否则它们不会。

希望我消除了一些困惑。

于 2011-03-15T17:09:06.960 回答