Укажите максимальное количество столбцов для WrapPanel в WPF
У меня есть WrapPanel, и я хочу указать максимальное количество его столбцов. Так, например, когда моя коллекция "ObjectCollection" (привязанная к этой WrapPanel) содержит только 4 элемента, WrapPanel будет иметь только одну строку. Но, когда "ObjectCollection" будет иметь 5 элементов, wrapPanel создаст еще одну строку, чтобы поместить пятую. (Мой Max_Columns_Number в этом случае равен 4).
Ответы
Ответ 1
Я уверен, что вы не можете сделать это с помощью 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>
Ответ 2
В принципе вам понадобится создать собственный Panel
для себя... теперь не унывайте... это не так сложно. Для начала ознакомьтесь с сообщениями, которые я предоставил для ссылок, которые объясняют, как создать пользовательский Panel
:
Как создать настраиваемую панель макета в WPF
Создание пользовательских панелей в WPF
Итак, теперь, когда вы знаете немного о создании пользовательских Panel
s, мы можем продолжить... вот что вам нужно:
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
... вот вспомогательный метод, который я вызываю из методов MeasureOverride
и ArrangeOverride
:
private void UpdateColumns(int currentColumn, Size finalSize)
{
leftColumnEdge = (finalSize.Width / ColumnCount) * currentColumn;
rightColumnEdge = (finalSize.Width / ColumnCount) * (currentColumn + 1);
columnWidth = rightColumnEdge - leftColumnEdge;
}
К сожалению, для вас я не могу предоставить вам полный пример, потому что мой пользовательский Panel
привязан к базовому классу AnimatedPanel
с большим количеством дополнительных функций. Однако для создания этого Panel
вам нужно создать методы MeasureOverride
и ArrangeOverride
. Если вы просто думаете логически об этом, это действительно не так сложно.
Ответ 3
Вы можете контролировать количество столбцов, задав ширину панели обертки. Я связываю ширину оберточной панели с ActualWidth контейнера, такого как Border. Таким образом, количество столбцов динамическое и основано на ширине окна.
<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>
Ответ 4
Иногда UniformGrid недостаточно:
- когда элементы имеют разные размеры или
- когда вы хотите элементы по вертикали и не хотите использовать другие обходные пути
В fooobar.com/info/352512/... можно найти WrapPanel с тем, что вы ищете.
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>
Результат:
![введите описание изображения здесь]()