WPF Grid指定单元格的方式是一个糟糕的设计

最近在自己的项目里尝试使用了WPF,说实话,感觉并不好。这里想谈谈目前碰到的最主要的问题,即:Grid指定单元格的设计方式并不合理。

回想一下我们在网页里是怎么指定单元格的。语法大概是这样:

< table >
    
< tr >
        
< td > </ td >
    
</ tr >
</ table >

 

而在WPF中指定这样的布局,要用一种完全不同的语法:


< Grid >
    
< Grid.RowDefinations >
        
< RowDefination    />
    
</ Grid.RowDefinations >
    
< Grid.ColumnDefinations >
        
< ColumnDefination    />
    
</ Grid.ColumnDefinations >
    
< TextBlock  Grid.Row ="0"  Grid.Column ="1"   />
</ Grid >

 

在这个项目之前,我已经了解了这种语法,并且(想像中)觉得它应该是有好处的,毕竟比起HTML来说,嵌套层次少了两层,应该比HTML更清楚吧。然而真正用的时候,我才发现这是错的!

 

问题在哪里呢?

原因之一:实际的XAML 相当冗长,每一个控件的常规属性、数据绑定表达式、事件处理函数用属性来表达,经常是密密麻麻的一大串。把样式提取出来也没有多大帮助,因为能提取的东西是有限的,而WPF累赘的数据绑定语法使得这种现象更加恶化。在这一大堆属性里面要找到哪一个Row和Column可真不是件愉快的事情——昨天当我调整完几个大的Grid以后,已经几乎没力气去看别的代码了。

HTML 其实要好看一些,虽然结构上的嵌套多了两层,但是哪个属于哪个基本上是一目了然的,因为结构上已经清楚了,看的时候不会也受到其他属性的干扰。最终我发现,减少嵌套层次并没有带来实际上的好处——虽然HTML的table嵌套到三层以上就已经很难理解了,可WPF也是一样。

 

原因之二:如果Grid最后添加一行,还要再翻到前面的RowDefinations再添加该行的定义,这是何必!因为对Grid最常见的操作就是添加行(或列),这样翻上翻下的额外工作实属多余。HTML不会有这种额外的负担。

 

原因之三:WPF它要求你自己记住控件和行列的对应关系,但是这样又带来一项额外的工作:如果在Grid中间插入一行,那么后面所有的行号都要跟着修改!幸好这种情况目前出现还不是很多,只有两次,但是这么一项简单的工作要付出的代价实在太大了。同样,HTML要插入一行也不需要什么其他的工作。

 

工作做完之后,我又考虑了一下 ,WPF这样设计究竟有什么好处?从前看到过的理由似乎没有什么特别站得住脚的。如果说原因是可以跳过空的单元格不指定,但实际上Grid中要空出的单元格通常远远少于要填充的单元格,而每个单元格都要设定Row和Column,这是为了满足20%的特殊问题而把80%的情况复杂化了,更何况HTML里指定一个空的<td></td>也算不上什么负担。如果说是为了简单修改一个属性就能够移动到别的位置,可实际操作的时候我修改属性以后几乎总是要跟着再操作一步,即把它移动到和标签出现顺序对应的位置上去。因为我发现单元格在文档中和在容器中的顺序如果不一致的话,只会让人糊涂,而且会增大以后犯错的机会。

 

结论:从项目实际操作结果来看,我只能认为Grid这样的设计是糟糕的。

 

 我得承认:自己使用WPF的时间并不长,理解也比较有限,所以这里的想法很有可能是错的。但我还是想说说自己用到目前为止的感觉,我觉得WPF有可能在方向上就错了。虽然WPF在设计上极端强调灵活性和扩展性,但也付出了代价——简单性和可读性在很大程度上丧失了。同样是设置样式,Style拖沓的语法和CSS的简洁性实在不可同日而语。那么这样冗长的语法到底带来了什么好处呢?另一方面,即使M$自己的工具也还不能够很好的适应这种新框架,面对复杂的绑定语法、模板、样式设定,可视化设计工具几乎无用武之地,许多东西还是不得不需要自己手工敲入,而且我已经看到比较复杂的XAML到了令人难以卒读的地步。

转载于:https://www.cnblogs.com/shuhari/archive/2009/06/15/wpf_grid_cell.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在WPF中,可以使用Grid控件的RowSpan属性来将行单元格合并为一行。 首先,在Grid中定义需要合并的行和列。通过设置Grid控件的行和列的定义,可以将单元格划分为多个区域。 然后,使用合并单元格方式,在需要合并的单元格上设置RowSpan属性。RowSpan属性指定单元格跨越的行数。 例如,如果我们有一个Grid控件有3行和3列,我们想将第1行的单元格合并为一行,可以按照以下步骤操作: 1. 定义Grid的行和列: ```xaml <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> </Grid> ``` 2. 使用合并单元格方式设置RowSpan属性: ```xaml <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="合并的单元格" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"/> </Grid> ``` 在这个例子中,我们将Grid的第一行的三个单元格合并为一行。通过设置TextBlock的Grid.Row="0"来指定其所在的行为第一行,并设置Grid.ColumnSpan="3"来指定跨越三列。 通过这种方式,我们可以将Grid的行单元格合并为一行。注意,WPF中的Grid控件还支持设置ColumnSpan属性来合并列单元格。 ### 回答2: 在WPF中,要将Grid的行单元格合并成一行,可以使用Grid控件中的RowSpan属性。 首先,使用Grid控件布局需要合并的行单元格。在XAML中,添加一个Grid控件,并设置好行和列的数量和宽度。 接下来,在需要合并的单元格中,设置RowSpan属性为要合并的行数。例如,如果需要将第一行的第一列和第二列合并为一行,可以将第一列和第二列的RowSpan属性设置为2。 以下是一个示例的XAML代码片段: ```xml <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Text="合并后的行" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"/> <TextBlock Text="第二列" Grid.Row="0" Grid.Column="1"/> <TextBlock Text="第一列" Grid.Row="1" Grid.Column="1"/> </Grid> ``` 在这个例子中,第一个TextBlock合并了第一行和第二行,而第二个和第三个TextBlock分别位于第一行和第二行的第二列。 通过设置RowSpan属性,可以将多个行单元格合并为一行,达到合并行的效果。 ### 回答3: 在WPF中,可以使用Grid控件的Grid.RowSpan属性来合并行中的单元格Grid控件是一种灵活的布局容器,可以将控件放置在不同的行和列中。 要将Grid的行单元格合并为一行,首先需要设置要合并单元格的控件的Grid.Row属性,指定其所在的行索引。然后,使用Grid控件的Grid.RowSpan属性,设置合并单元格的跨度。 例如,假设我们有一个Grid控件,其中有3行和3列。要将第一行的第一列和第二列合并为一行,我们可以使用以下代码: <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Button Content="Cell 1" Grid.Row="0"/> <Button Content="Cell 2" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"/> <Button Content="Cell 3" Grid.Row="1" Grid.Column="0"/> <Button Content="Cell 4" Grid.Row="1" Grid.Column="1"/> <Button Content="Cell 5" Grid.Row="1" Grid.Column="2"/> <Button Content="Cell 6" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"/> </Grid> 在上面的代码中,我们定义了一个Grid控件,其中有3行和3列。其中,第一行的第一列(Cell 1)和第二列(Cell 2)通过设置Grid.RowSpan属性为2,将它们的单元格合并为一行。同样地,第三行的所有列(Cell 6)通过设置Grid.ColumnSpan属性为3,将它们的单元格合并为一行。 通过使用Grid控件的Grid.RowSpan和Grid.ColumnSpan属性,可以轻松地合并行中的单元格,以满足特定的布局需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值