c# - Especifique el número máximo de columnas para un WrapPanel en WPF
list wpf c# (4)
Tengo un WrapPanel, y quiero especificar el número máximo de sus columnas. Entonces, por ejemplo, cuando mi Colección "ObjectCollection" (vinculada a este WrapPanel) contiene solo 4 elementos, el WrapPanel tendrá solo una fila. Pero, cuando "ObjectCollection" tendrá 5 elementos, el wrapPanel creará otra fila para poner la quinta. (Mi Max_Columns_Number en este caso es 4).
A veces el UniformGrid no es suficiente:
- cuando los artículos son de tamaños muy diferentes, o
- cuando quieres elementos verticalmente y no quieres usar otras soluciones
En esta publicación de puede encontrar un WrapPanel con lo que está buscando.
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>
Resultado:
Básicamente, necesitarás crear un Panel
personalizado para ti mismo ... ahora no te desanimes ... no es tan difícil. Para comenzar, eche un vistazo a las publicaciones para las que he proporcionado enlaces que explican cómo crear un Panel
personalizado:
Cómo crear un panel de diseño personalizado en WPF
Creación de paneles personalizados en WPF
Ok, ahora que sabe un poco más sobre la creación de Panel
personalizados, podemos continuar ... esto es lo que va a necesitar:
private int columnCount;
private double leftColumnEdge, rightColumnEdge, columnWidth;
public int ColumnCount
{
get { return columnCount; }
set
{
if (value < 1) value = 1;
columnCount = value;
}
}
Esta propiedad se usaría cuando declare su Panel
en Resources
:
<ItemsPanelTemplate x:Key="AnimatedPanel">
<Controls:AnimatedColumnWrapPanel ColumnCount="3" ... />
</ItemsPanelTemplate>
Tenga en cuenta que deberá declararlo dentro de un objeto ItemsPanelTemplate
porque eso es lo que espera la propiedad ItemsPanel
:
<ListBox ItemsPanel="{StaticResource AnimatedPanel}" ... />
Ahora volviendo al Panel
... aquí hay un método auxiliar al que llamo desde los métodos MeasureOverride
y ArrangeOverride
:
private void UpdateColumns(int currentColumn, Size finalSize)
{
leftColumnEdge = (finalSize.Width / ColumnCount) * currentColumn;
rightColumnEdge = (finalSize.Width / ColumnCount) * (currentColumn + 1);
columnWidth = rightColumnEdge - leftColumnEdge;
}
Desafortunadamente para usted, no puedo proporcionarle un ejemplo completo porque todos mis Panel
personalizados están vinculados a una clase básica de AnimatedPanel
con mucha funcionalidad adicional. Sin embargo, solo necesita crear los métodos MeasureOverride
y ArrangeOverride
para completar este Panel
. Si solo piensas con lógica, no es tan difícil.
Estoy bastante seguro de que no puedes hacerlo con un WrapPanel , pero puedes usar UniformGrid en UniformGrid lugar.
Ese tiene propiedades para especificar el número de filas y columnas que desea.
Si establece la propiedad Columns
en 4, mantendrá 4 elementos en cada fila y luego se ajustará a la siguiente.
<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>
Puede controlar el número de columnas configurando el ancho del panel de ajuste. Vinculo el ancho del panel de envoltura al Ancho real de un contenedor como Borde. De esa manera, el número de columnas es dinámico y se basa en el ancho de la ventana.
<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>