Frage

Ich habe eine Listbox und sie ist an eine Liste einfacher Objekte gebunden.Wie wir wissen, werden die Elemente der Listbox standardmäßig als Stackpanel gehostet und daher werden die Elemente auf diese Weise angeordnet

item1
item2
item3
item4
item5
item6

Allerdings habe ich einige Bedingungen, anhand derer ich überprüfe, ob der Artikel horizontal oder vertikal angezeigt werden soll und die Artikel daher auf diese Weise angeordnet werden könnten

Z.B :-

item1
item2
item3 item4 item 5
item6

Wie ist das möglich?

(Wenn Sie sich fragen, warum ich so etwas jemals brauchen sollte, wäre ein Beispielszenario „Facebook-Style-Updates“, bei dem ein Benutzer, wenn er 3-4 Fotos kontinuierlich hochlädt, nicht immer in der nächsten Zeile erscheint, sondern möglicherweise horizontal Wenn er ein Ereignis postet, erscheint es in der nächsten Zeile.)

Dank im Voraus :)

War es hilfreich?

Lösung

Die Grundlage der Lösung besteht darin, einen anderen ItemsControl im ItemTemplate des ListBoxs zu verwenden.Dieser ItemsControl sollte einen horizontal ausgerichteten StackPanel als ItemsPanel haben.

Hier ist ein grundlegendes Beispiel.Beginnen wir mit einigen sehr einfachen Testdaten: -

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

    }
}

Jetzt möchten wir diese Liste in einer ListBox anzeigen, aber alle Namen mit derselben ersten Initiale in derselben Zeile belassen.Ich werde eine Implementierung von IValueConverter verwenden, um mit der Gruppierung umzugehen, die wir benötigen.Wenn Sie MVVM verwenden, muss Ihr ViewModel dies übernehmen.

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();
    }
}

Die Ausgabe dieses Konverters ist im Grunde genommen IEnumerable<IEnumerable<string>>, was wir wollen.Die äußere ListBox listet die äußere Menge auf und der innere ItemsControl listet die innere Menge von Zeichenfolgen auf, die eine Menge von Namen mit derselben Initiale sind.

Hier ist das 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>

Andere Tipps

Bei Verwendung des MVVM-Muster Ich würde so etwas machen:

  1. Erstellen Sie ein ViewModel für die Ansicht, in der sich Ihr Listenfeld befindet.Diese VM enthält eine Sammlung von ListItemViewModel Instanzen (siehe nächster Punkt)
  2. Erstellen Sie ein ViewModel mit dem Namen ListItemViewModel (geben Sie ihm basierend auf Ihrer Domäne einen passenderen Namen).Dieses Ansichtsmodell enthält eine Sammlung von ItemViewModel-Instanzen (siehe nächster Punkt).
  3. Erstellen Sie ein ViewModel mit dem Namen ItemViewModel.Jedes davon unterstützt ein einzelnes Element in der Liste.Geben Sie diesem einen passenderen Namen, basierend auf Ihrer Domain.
  4. Erstellen Sie eine Ansicht, die Ihre Listbox enthält.Binden Sie Ihre Listbox an die Sammlung von ListItemViewModels in der VM.Die Elementvorlage für dieses Listenfeld ist eine ListItemView (siehe nächster Punkt).Die Elementpanel-Vorlage ist das Standard-StackPanel.
  5. Erstellen Sie eine ListItemView mit einem ListItemViewModel-Datenkontext.Diese Ansicht besteht aus einem horizontalen StackPanel von ItemViews (siehe nächster Punkt).
  6. Erstellen Sie eine ItemView, die vom ItemViewModel unterstützt wird.

Ihre Ansicht würde in etwa so aussehen, jeweils mit einem entsprechenden ViewModel.

Wie ich oben sagte, möchten Sie auf jeden Fall den Namen Ihrer Ansichten/Ansichtsmodelle ändern, meine dienen nur zu Demonstrationszwecken :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top