【WPF】完美的布局不留白——解决WrapPanel右侧留白问题

充分利用界面上的空间,是优秀软件界面布局设计的原则之一。如果布局上出现了大片的空白区域就会给人一种浪费和不谐调的感觉。如下图所示。

clip_image002

我们把ListBox的ItemsPanel设置为一个WrapPanel。让里面的Items可以自动折行。但是这样在ListBox的右侧,会出现一块空白区。很多情况下,我们对于Item的大小并不很在意,这时我们会更希望Item的宽度可以随着整体宽度自动地调节。产生如下图所示的效果。

clip_image004 clip_image006

但是系统自带的WrapPanel是做不到这一点的。这时我们就要用到自定义Panel了。看到上面的效果,可能有人会说用UniformGrid不就行了?如果里面的Item 一直是像上面3*6的固定布局是可以用UniformGrid的。或是你愿意动态计算UniformGrid有几行几列也可以。WrapPanel的特点是能动态地根据宽度调节每行Item的个数。如下图所示。

clip_image008

上面的自动缩放的WrapPanel的效果还是通过自定义Panel来实现的。类图如下。

clip_image010

使用这种方式进行布局,需要对这个FillWrapPanel里的Item有一些特殊的要求。

1. 不设置宽度、最小宽度、最大宽度。这些都在FillWrapPanel设置。

2. 支持缩放。当Item变大时,内部布局也要随之改变,并保持合理布局。说得简单点。Item和Item内部的所有东西(TextBlock除外),都不要设置固定的宽度和高度即可。

随便说几句关于自定义Panel的题外话。

在之前的文章中,已经介绍过两种自定义Panel。一种是有缩放的,一种也是Wrap的。有人可能要问,能不能把这两种Panel结合起来做一个天下无双的无比强大的Panel呢?答案是,如果有特定的规则来约束,是可以的。这个规则要满足下面的要求。

在此规则的约束下,通过界面的大小,可以唯一地确定内部所有Item的布局(大小和位置)。

这个听上去很费话,但是在自己实现一个Panel的过程中,很容易陷入逻辑之中,而忽视了这个简单的约束条件。所以如果能定义出规则满足上面的条件,逻辑上就可以实现出这样的Panel。但是作为一个第三方控件,你还要考虑到使用者的理解力。如果一个Panel的正确使用要靠长篇的文档和丰富的示例来保证。那这个Panel多数会被闲置,因为很少有布局会复杂到同时具有这些功能。即使做得出来,用户用上去,也会觉得奇怪。最优美的,也应该是最自然的。

在多数情况下,应该考虑用多个Panel的组合来实现复杂功能,而不是试图实现一个无比强大的自定义Panel。这才是符合软件设计模式的基本要求的。

我们言归正传。从上面的Panel的类图中,其实也就可以看出其实现方式。先计算出每行需要放置多少个Item,再计算出第个Item的宽度也就行了。

单独介绍一下FloorItemWidth的作用,这个属性用来设置是否让每个Item的宽度一定是个整数。如果宽度不是整数,TextBlock、Image等内容可能会变得很模糊。

具体的代码可以从这里下载。(仅供参考)

posted on 2010-02-21 13:15  南柯之石  阅读(8535)  评论(13编辑  收藏  举报

导航