在WPF中指定WrapPanel的最大列数

时间:2013-09-05 11:45:15

标签: c# wpf data-binding wrappanel

我有一个WrapPanel,我想指定其列的最大数量。因此,例如,当我的Collection“ObjectCollection”(绑定到此WrapPanel)仅包含4个元素时,WrapPanel将只有一行。但是,当“ObjectCollection”将包含5个元素时,wrapPanel将创建另一行以放置第五个元素。 (在这种情况下,我的Max_Columns_Number为4)。

4 个答案:

答案 0 :(得分:37)

我很确定你不能使用WrapPanel,但你可以改用UniformGrid

该属性具有指定所需行数和列数的属性。

如果将Columns属性设置为4,则每行保留4个项目,然后换行到下一个。

<UniformGrid Columns="4">
    <!-- In first row -->
    <Button Content="test"></Button>
    <Button Content="test"></Button>
    <Button Content="test"></Button>
    <Button Content="test"></Button>

    <!-- In second row -->
    <Button Content="test"></Button>
</UniformGrid>

答案 1 :(得分:7)

基本上你需要为自己创建一个自定义Panel ...现在不要感到沮丧...这不是那个很难。首先,请查看我提供链接的帖子,了解如何创建自定义Panel

How to create a Custom Layout Panel in WPF

Creating Custom Panels In WPF

好的,现在您已经了解了有关创建自定义Panel的更多信息,我们可以继续......这就是您需要的内容:

private int columnCount;
private double leftColumnEdge, rightColumnEdge, columnWidth;

public int ColumnCount
{
    get { return columnCount; }
    set
    {
        if (value < 1) value = 1;
        columnCount = value;
    }
}

此属性将用于您在Panel中声明Resources

的位置
<ItemsPanelTemplate x:Key="AnimatedPanel">
    <Controls:AnimatedColumnWrapPanel ColumnCount="3" ... />
</ItemsPanelTemplate>

请注意,您需要将声明在 ItemsPanelTemplate对象中,因为这是ItemsPanel属性所期望的:

 <ListBox ItemsPanel="{StaticResource AnimatedPanel}" ... />

现在回到Panel ...这是我从MeasureOverrideArrangeOverride方法调用的辅助方法:

private void UpdateColumns(int currentColumn, Size finalSize)
{
    leftColumnEdge = (finalSize.Width / ColumnCount) * currentColumn;
    rightColumnEdge = (finalSize.Width / ColumnCount) * (currentColumn + 1);
    columnWidth = rightColumnEdge - leftColumnEdge;
}

不幸的是,我无法为您提供完整的示例,因为我的自定义Panel都绑定到具有许多附加功能的基础AnimatedPanel类。但是,您只需创建MeasureOverrideArrangeOverride方法即可完成此Panel。如果你只是从逻辑上思考它,它真的并不那么困难。

答案 2 :(得分:1)

有时 UniformGrid 是不够的:

  • 当商品的尺寸大小不同时,或
  • 如果您想垂直放置项目而不想使用other workarounds

this stackoverflow post中可以找到您正在搜索的 WrapPanel

<强>的Xaml:

{{1}}

<强>结果:

enter image description here

答案 3 :(得分:0)

您可以通过设置包装面板的宽度来控制列数。我将包装面板的宽度绑定到像Border这样的容器的ActualWidth。这样,列数是动态的,并且基于窗口的宽度。

<Border Name="DataBorder" Grid.Row="0" Grid.Column="1"
        BorderBrush="Navy" BorderThickness="1,2,2,2"
        Padding="4">
        <Grid>
             <Grid.RowDefinitions>
                  <RowDefinition Height="Auto"></RowDefinition>
                  <RowDefinition Height="*"></RowDefinition>
              </Grid.RowDefinitions>

              <StackPanel>
                  <TextBlock Text="{Binding NewPictureCountDisplay}"></TextBlock>
              </StackPanel>

              <ListBox Name="NewFilesListBox" Grid.Row="1"
                       ItemsSource="{Binding CreatedFiles}">
                  <ListBox.ItemsPanel>
                      <ItemsPanelTemplate>
                          <WrapPanel Orientation="Horizontal" Width="{Binding ElementName=DataBorder, Path=ActualWidth}"></WrapPanel>
                      </ItemsPanelTemplate>
                  </ListBox.ItemsPanel>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*"></RowDefinition>
                                        <RowDefinition Height="Auto"></RowDefinition>
                                    </Grid.RowDefinitions>

                                    <Image Grid.Row="0" Source="{Binding FullPath}" Width="128" Height="128" Stretch="UniformToFill"></Image>

                                    <StackPanel Grid.Row="1" Orientation="Vertical">
                                        <Button Content="Import" Margin="2"></Button>
                                        <Button Content="Delete" Margin="2"></Button>
                                        <TextBlock HorizontalAlignment="Stretch" Text="{Binding FullPath}" Margin="2"></TextBlock>
                                        <TextBlock HorizontalAlignment="Stretch" Text="{Binding ChangeType}" Margin="2"></TextBlock>
                                    </StackPanel>

                                </Grid>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>