Как я могу получить этот тип макета в Silverlight? - PullRequest
1 голос
/ 24 марта 2011

У меня есть список, и он связан со списком простых объектов. Как мы знаем, в списке по умолчанию размещены элементы в виде Stackpanel, и поэтому он размещает элементы таким образом

item1
item2
item3
item4
item5
item6

Однако у меня есть некоторые условия, при которых я проверяю, должен ли элемент отображаться горизонтально или вертикально, и, следовательно, элементы могут быть размещены таким образом

Например: -

item1
item2
item3 item4 item 5
item6

Как это можно сделать?

(Если вам интересно, зачем мне такая вещь, пример сценария будет «обновления в стиле Facebook», где, если пользователь загружает 3-4 фотографии постоянно, они не всегда появляются на следующей строке, но это может появляются горизонтально, тогда как если он публикует какое-то событие, оно появляется в следующей строке.)

Заранее спасибо:)

Ответы [ 2 ]

4 голосов
/ 24 марта 2011

Если использовать шаблон MVVM , я бы сделал что-то вроде этого:

  1. Создайте ViewModel для представления, в котором находится ваш список. Эта виртуальная машина содержит коллекцию ListItemViewModel экземпляров (см. Следующий пункт)
  2. Создайте ViewModel с именем ListItemViewModel (дайте ему более подходящее имя в зависимости от вашего домена). Эта модель представления содержит коллекцию экземпляров ItemViewModel (см. Следующий пункт).
  3. Создать ViewModel с именем ItemViewModel. Каждый из них поддерживает один элемент в списке. Дайте этому более подходящее имя в зависимости от вашего домена.
  4. Создайте представление, содержащее ваш список. Свяжите свой список с коллекцией ListItemViewModels в виртуальной машине. Шаблон элемента для этого списка будет ListItemView (см. Следующий пункт). Шаблон панели элементов будет StackPanel по умолчанию.
  5. Создать ListItemView, который имеет контекст данных ListItemViewModel. Это представление состоит из горизонтальной StackPanel ItemViews (см. Следующий пункт).
  6. Создать ItemView, который поддерживается ItemViewModel.

Ваш вид будет выглядеть примерно так, у каждого будет соответствующая ViewModel.

Как я уже говорил выше, вы определенно захотите изменить название ваших представлений / моделей представлений, мои предназначены только для демонстрационных целей:)

1 голос
/ 24 марта 2011

Основой решения является использование другого ItemsControl в ItemTemplate из ListBox. Этот ItemsControl должен иметь горизонтальную ориентацию StackPanel как ItemsPanel.

Вот базовый пример. Начнем с очень простых тестовых данных: -

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

    }
}

Теперь мы хотим отобразить этот список в ListBox, но сохранить все имена с одинаковым первым инициалом в одной строке. Я собираюсь использовать реализацию IValueConverter, чтобы справиться с группировкой, которая нам нужна. Если вы используете MVVM, то вам понадобится 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();
    }
}

Выход этого конвертера в основном IEnumerable<IEnumerable<string>>, что нам и нужно. Внешний ListBox будет перечислять внешний набор, а внутренний ItemsControl будет перечислять внутренний набор строк, который будет набором имен с одинаковыми инициалами.

Вот 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>
...