I have a ItemsControl with a WrapPanel as ItemsHost and multiple Groupings. Got this going so far with the following Templates:
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" x:Name="PART_Header" Content="{TemplateBinding Content}" />
<ItemsPresenter Grid.Row="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
Now I have the Problem that every Group does start a new Column why I want it to Continue right under the last GroupItem and Wrap in the Middle of the GroupItem instead of at the beginning.
It should look like the Windows 8 Apps overview (not the start page, if you go down to the overview)
Is that possible?
I solved this in the ViewModel instead. I add a GroupItem into the ObservableCollection that is styled like a (Expandable) GroupHeader. Than I added a seperate DataTemplate for the GroupHeader that sets a IsCollapsed property on the Group. All Items do now have a reference to the parent Group and bind the Visibility to the IsCollapsed property of the Parent Group.
Sadly i was not able to achive this using the CollectionViewSource.
This is the XAML:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.DataContext>
<local:ViewModel/>
</ItemsControl.DataContext>
<ItemsControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<DataTemplate DataType="{x:Type local:GroupViewModel}">
<StackPanel>
<CheckBox IsChecked="{Binding IsExtended}" />
<!--Restyle to look like a extender-->
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ItemViewModel}">
<TextBlock Text="{Binding Name}"
Visibility="{Binding Group.IsExtended, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
This is the ViewModel:
public class ViewModel
{
public ViewModel()
{
//Some Test data
GroupViewModel group1 = new GroupViewModel("Group1");
GroupViewModel group2 = new GroupViewModel("Group2");
this.Items = new ObservableCollection<object>(new[]
{
new ItemViewModel("Item1", group1),
new ItemViewModel("Item2", group1),
new ItemViewModel("Item3", group2),
new ItemViewModel("Item4", group2)
});
string groupName = string.Empty;
foreach (ItemViewModel item in this.Items.ToArray())
{
//Insert Group headers
if (item.Group.Name != groupName)
{
groupName = item.Group.Name;
this.Items.Insert(this.Items.IndexOf(item), item.Group);
}
}
}
public ObservableCollection<object> Items { get; }
}
public class GroupViewModel : ViewModelBase
{
private bool isExtended = true;
public GroupViewModel(string name)
{
this.Name = name;
}
public string Name { get; }
public bool IsExtended
{
get { return this.isExtended; }
set { this.SetProperty(ref this.isExtended, value); }
}
}
public class ItemViewModel
{
public ItemViewModel(string name, GroupViewModel group)
{
this.Name = name;
this.Group = group;
}
public string Name { get; }
public GroupViewModel Group { get; }
}