visual template studio que net ejemplo wpf listview layout

template - WPF ListView con disposición horizontal de los elementos?



wpf listview grouping (5)

Quiero diseñar elementos en un ListView de manera similar al ListView de WinForms en modo Lista. Es decir, donde los elementos se disponen no solo verticalmente sino también horizontalmente en ListView.

No me importa si los artículos se presentan así:

1 4 7
2 5 8
3 6 9

O así:

1 2 3
4 5 6
7 8 9

Siempre que se presenten tanto vertical como horizontalmente para maximizar el uso del espacio disponible.

Lo más cerca que pude encontrar fue esta pregunta:

¿Cómo puedo hacer que los elementos ListView de WPF se repitan horizontalmente, como una barra de desplazamiento horizontal?

Que solo establece los elementos solo horizontalmente.


Además de la respuesta de @ Dennis, sobre WrapPanel perder virtualización, he encontrado una buena clase que implementa correctamente esto. Si bien la publicación sugerida por Ben Constable ( Parte 1 , Parte 2 , Parte 3 , Parte 4 ) es una buena introducción, no pude completar la tarea de un Wrap Panel.

Aquí hay una implementación: https://virtualwrappanel.codeplex.com/ Lo he probado con un total de 3.300 videos y fotos, cargar la lista en sí es por supuesto un poco largo, pero eventualmente está virtualizando correctamente la lista, sin desplazamiento rezago en absoluto

  • Hay algunos problemas en este código, consulte la pestaña de problemas en la página anterior.

Después de agregar el código fuente a su proyecto, ejemplo de código fuente:

<!--in your <Window> or <UserControl> tag --> <UserControl xmlns:hw="clr-namespace:Project.Namespace.ToClassFile" > <!--...--> <ListView x:Name="lvImages" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Margin="10" Height="auto" ItemsSource="{Binding ListImages}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" > <ListView.ItemsPanel> <ItemsPanelTemplate> <hw:VirtualizingWrapPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListView.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical" Margin="5" MaxHeight="150"> <TextBlock Text="{Binding title}" FontWeight="Bold"/> <Image Source="{Binding path, IsAsync=True}" Height="100"/> <TextBlock Text="{Binding createDate, StringFormat=dd-MM-yyyy}"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>

Back-end de estilo MVVM, por lo que esto está dentro del ViewModel:

public ObservableCollection<Media> ListImages { get { return listImages; } set { listImages = value; OnPropertyChanged(); } } //Just load the images however you do it, then assign it to above list. //Below is the class defined that I have used. public class Media { private static int nextMediaId = 1; public int mediaId { get; } public string title { get; set; } public string path { get; set; } public DateTime createDate { get; set; } public bool isSelected { get; set; } public Media() { mediaId = nextMediaId; nextMediaId++; } }


En mi caso, la mejor opción fue usar:

<ListView.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Vertical" MaxHeight="{Binding (FrameworkElement.ActualHeight), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" MinHeight="{Binding ItemHeight, RelativeSource={RelativeSource Self}}" ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}"/> </ItemsPanelTemplate> </ListView.ItemsPanel>

Esto me dio un análogo decente a la opción de lista de Windows Explorer


Recientemente investigué cómo lograr esto en WPF y encontré una buena solución. Lo que quería era replicar el modo Lista en el Explorador de Windows, es decir, de arriba a abajo, luego de izquierda a derecha.

Básicamente, lo que desea hacer es anular la propiedad ListBox.ItemsPanel para usar un WrapPanel con su orientación establecida en Vertical.

<ListBox> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Vertical"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>

Sin embargo, esto SERÁ lento al cargar un gran conjunto de datos, ya que el panel de ajuste no está virtualizado. Esto es importante. Por lo tanto, esta tarea ahora se vuelve un poco más ya que ahora necesita escribir su propio VirtualizedWrapPanel extendiendo VirtualizedPanel e implementando IScrollInfo.

public class VirtualizedWrapPanel : VirtualizedPanel, IScrollInfo { // ... }

Esto es lo que tengo en mi investigación antes de tener que ir a otra tarea. Si quieres más información o ejemplos, por favor comenta.

ACTUALIZAR . Ben Constable''s tiene una gran serie sobre cómo implementar IScrollInfo .

Hay 4 artículos en total. Una muy buena lectura.

Desde entonces he implementado un panel de ajuste virtualizado, no es una tarea fácil, incluso con la ayuda de la serie de artículos anterior.


Suena como que lo que estás buscando es un WrapPannel , que colocará los elementos horizontalmente hasta que no haya más espacio, y luego pasará a la siguiente línea, así:

( MSDN )
texto alternativo http://i.msdn.microsoft.com/Cc295081.b1c415fb-9a32-4a18-aa0b-308fca994ac9(en-us,Expression.10).png

También podría usar un UniformGrid , que colocará los elementos en un número determinado de filas o columnas.

La forma en que obtenemos los elementos para arreglar usando estos otros paneles en un ListView, ListBox o cualquier forma de ItemsControl es cambiando la propiedad ItemsPanel . Al establecer el Panel de elementos, puede cambiarlo del StackPanel predeterminado que utilizan los ElementosControles. Con WrapPanel también debemos establecer los anchos como se muestra aquí .

<ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}" ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" /> </ItemsPanelTemplate> </ListView.ItemsPanel> ... </ListView>


de izquierda a derecha, uso de arriba a abajo

<ListView.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" MaxWidth="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type er:MainWindow}}}"/> </ItemsPanelTemplate> </ListView.ItemsPanel>