Может ли ItemsControl сгруппировать связанную коллекцию?
Я пытаюсь определить, есть ли способ использовать 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 ответ
Я нашел способ сделать это, вложив новый элемент 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();
}
}