ItemsControl(WrapPanel)分组应该拆分GroupItems

时间:2015-05-07 08:35:29

标签: wpf wrappanel

我有一个ItemsControl,其中WrapPanel为ItemsHost和多个分组。 到目前为止,使用以下模板:

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

现在我遇到的问题是,每个Group都会启动一个新列,为什么我希望它在GroupItem的最后一个GroupItem和Wrap中继续,而不是在开头。

它应该看起来像Windows 8应用程序概述(如果您转到概述,则不是起始页面)

这可能吗?

2 个答案:

答案 0 :(得分:2)

我在ViewModel中解决了这个问题。我将一个GroupItem添加到ObservableCollection中,其样式类似于(可扩展的)GroupHeader。 我为GroupHeader添加了一个单独的DataTemplate,用于在Group上设置IsCollapsed属性。所有项目现在都具有对父组的引用,并将可见性绑定到父组的IsCollapsed属性。

可悲的是,我无法使用CollectionViewSource实现此目的。

这是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>

这是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; }
}

答案 1 :(得分:1)

你不能直接进行那种包装,因为群组在一个面板中,而每个群组中的项目都在他们自己的面板中。

您有两种选择:

  • 使用viewmodel和Datatemplates的组合来模拟分组。 ItemsSource不会被分组CollectionView,只是普通集合,但项目将包含组名。在DataTemplate中,您将显示每个组中第一个项目的Group Header。

  • 创建您自己的控件,可以将子项安排到开箱即用的组中。相当一部分工作,但更好的可重用性。我相信这就是WinRT GridView和ListView分组的工作原理。也许你可以在WPF中找到simmilar第三方控件