c# wpf data-binding wrappanel

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>