Pregunta

Tengo un listbox y se enlaza a una lista de objetos simples.Como sabemos el cuadro de lista por defecto que tiene es la del host de elementos como un Stackpanel y por lo que establece los artículos en esta moda

item1
item2
item3
item4
item5
item6

Sin embargo, tengo algunas condiciones a través de la cual puedo comprobar si el elemento se muestre en horizontal o vertical y, por tanto, los elementos pueden ser colocados en esto de la moda

Por ejemplo :-

item1
item2
item3 item4 item 5
item6

¿Cómo es posible hacer esto?

(Si usted se está preguntando por qué yo nunca la necesidad de tal cosa, un ejemplo sería la situación de "facebook estilo de actualizaciones", en la que si un usuario carga 3-4 fotos continuamente que no siempre aparecen en la siguiente línea, pero puede aparecer de forma horizontal, mientras que si los puestos de algunos sucesos que aparece en la línea siguiente.)

Gracias de antemano :)

¿Fue útil?

Solución

El fundementals de la solución es usar otro ItemsControl en el ItemTemplate de la ListBox.Este ItemsControl debe tener una horizontal orientados a la StackPanel como su ItemsPanel.

Aquí hay un ejemplo básico.Vamos a empezar con algo muy sencillo testdata:-

public class TestStringList : List<string>
{
    public TestStringList()
    {
        AddRange(new[] {"Anthony", "Kar", "Martin", "Jon", "Erik", "Darin",
            "Balus", "Mike", "Hans", "Alex", "Anomie", "David" });

    }
}

Ahora queremos mostrar esta lista en un ListBox, pero mantener todos los nombres que tienen las mismas iniciales, en la misma línea.Voy a usar una aplicación de IValueConverter para lidiar con la agrupación que necesitamos.Si usted está usando MVVM entonces usted tendría su ViewModel toma de este.

public class Grouper : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((IEnumerable<string>)value).OrderBy(s => s).GroupBy(s => s[0]);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

La salida de este convertidor es básicamente IEnumerable<IEnumerable<string>> que es lo que queremos.El exterior de cuadro de lista se enumera el externo y el interno ItemsControl se enumera el interior del conjunto de cadenas que será un conjunto de nombres con la misma inicial.

Aquí está el código xaml:-

<UserControl x:Class="SilverlightApplication1.SimpleGrouping"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SilverlightApplication1"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <local:TestStringList x:Key="TestData" />
        <local:Grouper x:Key="grouper" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <ListBox ItemsSource="{Binding Converter={StaticResource grouper}, Source={StaticResource TestData}}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal" />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding}" Margin="5" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

Otros consejos

Si el uso de la Patrón MVVM Me gustaría hacer algo como esto:

  1. Crear un ViewModel para la visualización en el cuadro de lista está en.Esta máquina virtual contiene una colección de ListItemViewModel instancias (ver siguiente punto)
  2. Crear un ViewModel llamado ListItemViewModel (dar un nombre más apropiado, basado en su dominio).Este modelo de vista contiene una colección de ItemViewModel instancias (ver siguiente punto).
  3. Crear un ViewModel llamado ItemViewModel.Cada uno de estos espaldas de un solo elemento en la lista.Dar a este un nombre más apropiado, basado en su dominio.
  4. Crear una Vista que contiene el cuadro de lista.Enlazar tu listbox a la colección de ListItemViewModels en la VM.La plantilla de elemento de este cuadro de lista, será un ListItemView (ver siguiente punto).Los elementos de la plantilla del panel será el predeterminado StackPanel.
  5. Crear un ListItemView que tiene un ListItemViewModel el contexto de los datos.Este punto de vista consiste en una horizontal StackPanel de ItemViews (ver siguiente punto).
  6. Crear un ItemView que está respaldado por la ItemViewModel.

Su punto de vista sería algo como esto, cada una de las correspondientes ViewModel.

Como he dicho anteriormente, usted definitivamente quiere cambiar el nombre de sus puntos de vista/ver modelos, los míos son para fines de demostración solamente :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top