Specify the max number of columns for a WrapPanel in WPF

百般思念 提交于 2020-01-01 02:10:13

问题


I have a WrapPanel, And I want to specify the Max number of its columns. So, for example, when my Collection "ObjectCollection" (binded to this WrapPanel) contains only 4 elements, the WrapPanel will have only one row. But, when "ObjectCollection" will have 5 elements, the wrapPanel will create another row to put the fifth one. (My Max_Columns_Number in this case is 4).


回答1:


I'm pretty sure you can't do it with a WrapPanel, but you can use the UniformGrid instead.

That one has properties to specify the number of rows and columns you want.

If you set the Columns property to 4, it will keep 4 items in each row, and then wrap to the next one.

<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>



回答2:


Basically you're going to need to create a custom Panel for yourself... now don't get despondent... it's not that difficult. To start with, please take a look at the posts that I have provided links for that explain how to create a custom Panel:

How to create a Custom Layout Panel in WPF

Creating Custom Panels In WPF

Ok, so now that you know a bit more about creating custom Panels, we can continue... here's what you're going to need:

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

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

This property would be used where you declare your Panel in Resources:

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

Note that you will need to declare it inside an ItemsPanelTemplate object because that is what the ItemsPanel property expects:

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

Now back to the Panel... here is a helper method that I call from the MeasureOverride and ArrangeOverride methods:

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

Unfortunately for you, I cannot provide you with a complete example because my custom Panels are all tied into a base AnimatedPanel class with lots of additional functionality. However, you only need to create the MeasureOverride and ArrangeOverride methods to complete this Panel. If you just think logically about it, it's really not that difficult.




回答3:


Sometimes the UniformGrid is not enough:

  • when items are of very different sizes, or
  • when you want items vertically and don't want to use other workarounds

In this stackoverflow post can be found a WrapPanel with what you are searching for.

Xaml:

<loc:WrapPanelWithRowsOrColumnsCount
    xmlns:loc="clr-namespace:..."
    Orientation="Vertical"
    RowsOrColumnsCount="2">
    <TextBox Text="Andrew" Margin="2" Height="30" />
    <TextBox Text="Betty" Margin="2" Height="40" />
    <TextBox Text="Celine" Margin="2" Height="20" />
    <TextBox Text="Dick" Margin="2" Height="20" />
    <TextBox Text="Enron" Margin="2" Height="30" />
    <TextBox Text="Felix" Margin="2" Height="20" />
    <TextBox Text="Hanibal" Margin="2" Height="30" />
</loc:WrapPanelWithRowsOrColumnsCount>

Result:




回答4:


You can control the number of columns by setting the width of the wrap panel. I bind the width of the wrap panel to the ActualWidth of a container like Border. That way, the number of columns is dynamic and is based on the width of the window.

<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>


来源:https://stackoverflow.com/questions/18635431/specify-the-max-number-of-columns-for-a-wrappanel-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!