我正在开发一个WPF应用程序,我有一个ListBox
。
<ListBox Grid.Column="1" ItemsSource="{Binding MyUserControls}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
当用户点击按钮时,我将UserControl
实例添加到MyUserControls(ObservableCollection
)。 Listbox
位于我主窗口的Grid
中。我需要的是当添加越来越多的用户控件时,他们应该动态调整大小到最小宽度,然后添加到下一行。但我无法做到这一点。我能够获得wrappanel行为,但元素没有调整大小(我必须设置宽度属性,以确保连续只有3个用户控件)。即使添加了一个用户控件,它也不会填满整个网格。
如果您需要更多信息,请告诉我。
答案 0 :(得分:2)
互联网上已经有很多漂亮的东西可以告诉你如何拥有这样的WrapPanel。这是一个:
public class ElasticWrapPanel : Panel
{
/// <summary>
/// Identifies the <see cref="DesiredColumnWidth"/> dependency property.
/// </summary>
internal static readonly DependencyProperty DesiredColumnWidthProperty = DependencyProperty.Register("DesiredColumnWidth", typeof(double), typeof(ElasticWrapPanel), new PropertyMetadata(100d, new PropertyChangedCallback(OnDesiredColumnWidthChanged)));
private int _columns;
protected override Size MeasureOverride(Size availableSize)
{
_columns = (int) (availableSize.Width / DesiredColumnWidth);
foreach (UIElement item in this.Children)
{
item.Measure(availableSize);
}
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
if (_columns != 0)
{
double columnWidth = Math.Floor(finalSize.Width/_columns);
double top = 0;
double rowHeight = 0;
int column = 0;
foreach (UIElement item in this.Children)
{
item.Arrange(new Rect(columnWidth * column, top, columnWidth, item.DesiredSize.Height));
column++;
rowHeight = Math.Max(rowHeight, item.DesiredSize.Height);
if (column == _columns)
{
column = 0;
top += rowHeight;
rowHeight = 0;
}
}
}
return base.ArrangeOverride(finalSize);
}
private static void OnDesiredColumnWidthChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var panel = (ElasticWrapPanel)obj;
panel.InvalidateMeasure();
panel.InvalidateArrange();
}
public double DesiredColumnWidth
{
get
{
return (double)GetValue(DesiredColumnWidthProperty);
}
set
{
SetValue(DesiredColumnWidthProperty, value);
}
}
}
在xaml中,您将拥有以下内容:
<c:ElasticWrapPanel DesiredColumnWidth="200">
<Button Content="Item1" />
<Button Content="Item2" />
<Button Content="Item3" />
<Button Content="Item4" />
<Button Content="Item5" />
<Button Content="Item6" />
</c:ElasticWrapPanel>
答案 1 :(得分:1)
您描述的行为是WrapPanel
的正常行为。如果您希望Panel
自动填充每行的空间,则需要为自己创建自定义Panel
。如果你擅长数学,那么创建一个自定义Panel
并不像看起来那么困难...只有两种方法可以覆盖你计算每个元素的大小。
您可以通过以下链接找到热门来创建自定义Panel
:
How to create a Custom Layout Panel in WPF
Creating Custom Panels In WPF
Custom Panel Elements section of Panels Overview