有没有办法在 wpf wrappanel 中显示不同宽度的项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13102716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to display items of varying width in wpf wrappanel
提问by Mat J
I'm trying something like a windows 8 tiles and want to display tiles of varying width and/or height. WrapPanelmakes each column equal width and height leaving blank spaces around the smaller items. Is there a way or a panel to display items much like a StackPanelwhere each items can have individual dimensions and wrap like a WrapPanel?
我正在尝试类似 windows 8 的瓷砖,并希望显示不同宽度和/或高度的瓷砖。WrapPanel使每一列的宽度和高度相等,在较小的项目周围留下空白空间。有没有一种方法或面板来显示类似于 a 的StackPanel项目,其中每个项目都可以具有单独的尺寸并像 a 一样包裹WrapPanel?
Edit:
This is my ItemsControl. I replaced the Tile DataTemplate with a simple Borderand TextBlock. Width is autoand Tiles looks fine except WrapPanelcreate equal sized cells.
编辑:这是我的ItemsControl. 我用一个简单的Border和TextBlock. Width isauto和 Tiles 看起来不错,除了WrapPanel创建相同大小的单元格。
<ItemsControl ItemsSource="{Binding Path=Contents}" HorizontalContentAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="#B1DBFC" Height="200px" BorderBrush="#404648" Margin="5">
<TextBlock VerticalAlignment="Center" Text="{Binding Path=Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>


You can see from the image that the widthof each column is the width of widest item.
从图中可以看出width,每列的 是最宽项的宽度。
If I set the width explicitly on the border, things get more ugly.

如果我在边框上明确设置宽度,事情会变得更难看。

采纳答案by Benjamin Gale
The behaviour you are looking for is the defaultbehaviour of the WrapPanelas can be seen from the following sample.
您正在寻找的行为是 的默认行为,WrapPanel从以下示例中可以看出。
<WrapPanel >
<WrapPanel.Resources>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Width"
Value="80" />
<Setter Property="Height"
Value="80" />
<Setter Property="Margin"
Value="3" />
<Setter Property="Fill"
Value="#4DB4DD" />
</Style>
</WrapPanel.Resources>
<Rectangle Width="150" />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle Width="200"/>
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle Width="220"/>
<Rectangle />
<Rectangle />
</WrapPanel>
Which produces the following result:
这产生以下结果:


As you can see, The width of each item is honoured.
如您所见,每个项目的宽度都受到尊重。
Your problem is caused by setting the orientation of the WrapPanelto Verticalin your template. This is laying out the items from top-to-bottom rather than left-to-right which means that it is the Heightproperty that you need to be setting (or you could revert back to horizontal layout as in my example).
您的问题是由在模板中设置WrapPanelto的方向引起的Vertical。这是从上到下而不是从左到右布置项目,这意味着它是Height您需要设置的属性(或者您可以像我的示例一样恢复为水平布局)。
Compare your output to my screenshot where the panel is set to horizontal orientation; each rowis the size of the highest Rectangle. Don't believe me? Try setting one of the Rectangle'sHeightproperty to a larger value and you will observe that the row size will increase and the Rectanglesno longer line up vertically.
将您的输出与面板设置为水平方向的屏幕截图进行比较;每一行的大小都是最高的Rectangle。不相信我?尝试将Rectangle'sHeight属性之一设置为更大的值,您将观察到行大小会增加并且Rectangles不再垂直排列。
Reading your comments I think the best way to get started is to do the following:
阅读您的评论,我认为最好的入门方法是执行以下操作:
- Have a
WrapPanelthat lays out its content horizontally. - Items should have uniform
Height. - Constrain the
Heightof theWrapPanelto a certain size so that you don't get vertical scrollbars.
- 有一个
WrapPanel水平排列其内容的。 - 物品应该有统一的
Height。 - 约束
Height的WrapPanel到一定的规模,这样你就不会得到垂直滚动条。
The height of your WrapPanelshould be worked out using the following formula:
你的高度WrapPanel应该使用以下公式计算出来:
((Height of item + Top Margin + Bottom Margin) x Number of rows))
((项目高度 + 上边距 + 下边距)x 行数))
The width of each item also requires a bit of thought so that the panel lays the items out horizontally like the metro interface (lined up rather than staggered).
每个项目的宽度也需要考虑一下,以便面板像地铁界面一样水平放置项目(排列而不是交错)。
There are two tile sizes; the small one is 80px wide and the large one is 166px wide. The width of the large tile is worked out like this:
有两种瓷砖尺寸;小的80px宽,大的166px宽。大瓷砖的宽度是这样计算的:
(item width * 2) + (left margin + right margin)
(项目宽度 * 2) + (左边距 + 右边距)
This ensures the tiles line up correctly.
这可以确保瓷砖正确排列。
So now my XAML looks something like this:
所以现在我的 XAML 看起来像这样:
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal"
Margin="10,0">
<StackPanel.Resources>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Width"
Value="80" />
<Setter Property="Height"
Value="80" />
<Setter Property="Margin"
Value="3" />
<Setter Property="Fill"
Value="#4DB4DD" />
</Style>
<Style TargetType="{x:Type WrapPanel}">
<Setter Property="Margin"
Value="0,0,25,0" />
<Setter Property="MaxWidth"
Value="516" />
</Style>
</StackPanel.Resources>
<WrapPanel Height="258">
<Rectangle Width="166" />
<Rectangle />
<Rectangle Width="166" />
<Rectangle />
<Rectangle Width="166" />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle Width="166" />
<Rectangle />
</WrapPanel>
<WrapPanel Height="258">
<Rectangle />
<Rectangle Width="166" />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle />
<Rectangle Width="166" />
<Rectangle />
</WrapPanel>
</StackPanel>
</ScrollViewer>
Which produces the following result:
这产生以下结果:


This should give you enough information to start to re-factor this into a full control. If you do this then keep the following in mind:
这应该为您提供足够的信息来开始将其重新考虑为完全控制。如果您这样做,请记住以下几点:
- The layout properties (small item size, large item size, gaps etc) should be calculated rather than hard coded so that if you want to change, for example, the margins, the layout will still work correctly (I.E. the tiles will still line up).
- I would limit the number of 'tiles' that can be displayed (in the current example, if the tiles do not fit in the layout they are simply hidden which is probably not what you want).
- 应该计算布局属性(小项目大小、大项目大小、间隙等)而不是硬编码,这样如果你想改变,例如,边距,布局仍然可以正常工作(即瓷砖仍然会对齐)。
- 我会限制可以显示的“磁贴”的数量(在当前示例中,如果磁贴不适合布局,它们只是隐藏起来,这可能不是您想要的)。

