为什么WPF网格使用行和列的附加属性?

时间:2014-06-10 14:05:38

标签: .net wpf

在WPF中,如果我想使用Grid布局,我需要设置行和列定义......

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <!-- Cell data goes here -->
</Grid>

...然后使用附加的Grid.RowGrid.Column属性定义网格中项目的位置:

<TextBlock Text="Name:" Grid.Row="0" Grid.Column="0" />
<TextBox Text="{Binding Path=Name}" Grid.Row="0" Grid.Column="1" />

<TextBlock Text="Age:" Grid.Row="1" Grid.Column="0" />
<TextBox Text="{Binding Path=Age}" Grid.Row="1" Grid.Column="1" />

这至少会产生两个我能想到的问题:

  1. 如果我有一堆行并希望在第一行之后插入内容,那么我需要为第二行以后的所有项目重新分配Grid.Row
  2. 如果我决定隐藏一行(例如,根据用户是否拥有特定权限),该行仍将占用相同的空间。
  3. 使用附加属性显式地注释网格中每个元素的位置与HTML方法形成对比,其中行和单元格是按顺序定义的:

    <table>
        <tr><td>Name:</td><td>John</td></tr>
        <tr><td>Age:</td><td>15</td></tr>
    </table>
    

    在HTML中,上面提到的场景很容易解决。您只需插入一行即可插入新行:

    <table>
        <tr><td>Title:</td><td>Mr.</td></tr> <!-- insert win -->
        <tr><td>Name:</td><td>John</td></tr>
        <tr><td>Age:</td><td>15</td></tr>
    </table>
    

    ...并删除一行......删除它:

    <table>
        <tr><td>Title:</td><td>Mr.</td></tr> <!-- insert win -->
        <tr><td>Name:</td><td>John</td></tr>
        <!-- no more age! and it doesn't take up space any more either -->
    </table>
    

    我非常清楚WPF与HTML非常不同。为什么WPF设计师采用这种方法?有没有办法解决上述问题?

2 个答案:

答案 0 :(得分:4)

这确实是非常烦人的事情。

在场景中,我需要将项目堆叠在另一个之下,我只使用StackPanel。 但是如果你真的想要网格功能,那就有一个非常简洁的解决方案:

AutoGrid

使用AutoGrid可以定义行数和列数,并且为网格添加的每个元素都会自动分配行和列值:

<AutoGrid RowCount="2" RowHeight="35" Columns="100,auto">
  <Label />
  <TextBox />
  <Label />
  <TextBox />
</AutoGrid>

修改

我忘了提及UniformGrid,与AutoGrid不同,它实际上包含在框架中。

答案 1 :(得分:3)

它只是权力权衡的另一个例子,用于更多规范。您可以更多地控制WPF中的网格,但代价是必须指定更多属性。您不需要在HTML中指定尽可能多的内容,因为它会假设您将如何使用该标记 - 这可能是好的也可能是坏的。如果我不希望我的所有行默认具有相同的高度怎么办?用HTML声明星形符号要困难多少?&#34;

然而,我并不认为它和你想象的那样不同。为了动态隐藏该HTML 在行中,您必须将display设置为none,在WPF中,您必须将Visibility设置为Collapsed并更改RowDefinition& #39; s Height

设计师采用这种方法的原因是它确实允许更大的灵活性 - Grid主要是布局管理器,而不是表格显示。附加的属性方法(再次,以必须指定更多属性为代价)提供了更多的控制,这对于布局管理器来说很重要(尽管是的,如果你曾经做过GUI,它们有时会很痛苦。 )。

此外,为了向网格动态添加行以显示数据,您可能不会使用Grid,而是DataGrid。您也可以使用UniformGrid,它类似于HTML的表格(尽管这仍然是一个布局管理器)。还有一个Table类。