Может ли ItemsControl сгруппировать связанную коллекцию? - PullRequest
0 голосов
/ 26 января 2012

Я пытаюсь определить, есть ли способ использовать ItemsControl для группировки элементов в ItemsSource в отдельные ItemsPanels. В частности, я пытаюсь создать представление так, чтобы коллекция, скажем, 8 элементов могла быть перечислена в виде сетки, как UniformGrid, но с четными результатами, а не пустыми ячейками.

В то время как UniformGrid с 8 элементами в источнике будет давать результаты, подобные следующим:

-------------------------------------
- +++++++++ - +++++++++ - +++++++++ -
-------------------------------------
- +++++++++ - +++++++++ - +++++++++ -
-------------------------------------
- +++++++++ - +++++++++ - ooooooooo -
-------------------------------------

(последняя ячейка пуста)

Я пытаюсь получить результаты примерно так:

-------------------------------------
- +++++++++ - +++++++++ - +++++++++ -
-------------------------------------
- +++++++++ - +++++++++ - +++++++++ -
-------------------------------------
- +++++++++++++++ - +++++++++++++++ -
-------------------------------------

Если я программно разбиваю его, я могу легко получить отображение, вложив его так:

<StackPanel Orientation="Horizontal">
   <UniformGrid>
      item 1
      item 2
      item 3
   </UniformGrid>
   <UniformGrid>
      item 4
      item 5
      item 6
   </UniformGrid>
   <UniformGrid>
      item 7
      item 8
   </UniformGrid>
</StackPanel>

Но я бы хотел получить желаемые результаты только через Xaml.

1 Ответ

0 голосов
/ 31 января 2012

Я нашел способ сделать это, вложив новый ItemsControl в DataTemplate объекта, привязанного к коллекции, и используя ValueConverter для преобразования коллекции в массив массивов.

<ItemsControl ItemsSource="{Binding MyCollection, Converter={StaticResource ArraySplitConverter}, ConverterParameter=3}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid IsItemsHost="True" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Title} />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

ИValueConverter:

public class ArraySplitConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int param = System.Convert.ToInt16(parameter);
        object[] coll = (object[])value;
        ArrayList outer = new ArrayList();
        ArrayList inner = new ArrayList();

        for (int i = 0; i < coll.Length; i++)
        {
            inner.Add(coll[i]);
            if (((i + 1) % param == 0) || (i == coll.Length - 1)) { outer.Add(inner); inner = new ArrayList(); }
        }

        return outer;
    }

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