Domanda

Ho una casella di riepilogo ed è associata a un elenco di oggetti semplici.Come sappiamo la casella di riepilogo per impostazione predefinita ha i suoi elementi ospitati come Stackpanel e quindi dispone gli elementi in questo modo

item1
item2
item3
item4
item5
item6

Tuttavia ho alcune condizioni attraverso le quali controllo se l'articolo deve essere visualizzato orizzontalmente o verticalmente e quindi gli articoli potrebbero essere disposti in questo modo

Ad esempio: -

item1
item2
item3 item4 item 5
item6

Come è possibile farlo?

(Se ti stai chiedendo perché mai dovrei aver bisogno di una cosa del genere, uno scenario di esempio potrebbe essere "aggiornamenti in stile facebook" in cui se un utente carica 3-4 foto continuamente, queste non appaiono sempre nella riga successiva ma potrebbeappaiono orizzontalmente mentre se pubblica un evento appare nella riga successiva.)

Grazie in anticipo :)

È stato utile?

Soluzione

Il fondamento della soluzione è utilizzare un altro ItemsControl nel ItemTemplate del ListBox.Questo ItemsControl deve avere un StackPanel orientato orizzontalmente come ItemsPanel.

Ecco un esempio di base.Iniziamo con alcuni dati di test molto semplici: -

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

    }
}

Ora vogliamo visualizzare questo elenco in un ListBox ma mantenere tutti i nomi che hanno la stessa prima iniziale sulla stessa riga.Userò un'implementazione di IValueConverter per gestire il raggruppamento di cui abbiamo bisogno.Se stai usando MVVM, allora dovresti farlo con il tuo ViewModel.

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

L'output di questo convertitore è fondamentalmente IEnumerable<IEnumerable<string>> che è quello che vogliamo.Il ListBox esterno enumererà il set esterno e il ItemsControl interno enumererà il set interno di stringhe che sarà un insieme di nomi con la stessa iniziale.

Ecco 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>

Altri suggerimenti

Se si utilizza MVVM pattern Vorrei fare qualcosa del genere:

  1. Crea un ViewModel per la visualizzazione in cui si trova la tua casella di riepilogo. Questa VM contiene una raccolta di istanze ListItemViewModel (vedi punto successivo)
  2. Crea un ViewModel chiamato ListItemViewModel (dagli un nome più appropriato, in base al tuo dominio). Questo modello di visualizzazione contiene una raccolta di istanze di ItemViewModel (vedere il punto successivo).
  3. Crea un ViewModel chiamato ItemViewModel. Ciascuno di questi sostiene un singolo elemento nell'elenco. Assegna a questo un nome più appropriato in base al tuo dominio.
  4. Crea una vista che contenga la tua casella di riepilogo. Associa la tua casella di riepilogo alla raccolta di ListItemViewModels nella VM. Il modello di elemento per questa casella di riepilogo sarà un ListItemView (vedere il punto successivo). Il modello del pannello degli elementi sarà lo StackPanel predefinito.
  5. Crea un ListItemView con un contesto dati ListItemViewModel. Questa visualizzazione è costituita da uno StackPanel orizzontale di ItemViews (vedere il punto successivo).
  6. Crea un ItemView supportato da ItemViewModel.

La tua visualizzazione sarebbe simile a questa, ciascuna con un ViewModel corrispondente.

Come ho detto sopra, vorrai sicuramente cambiare il nome delle tue viste / modelli di visualizzazione, i miei sono solo a scopo dimostrativo :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top