7

I have a ListView Control bound to a ListCollectionView in a ViewModel.

I wanted to try to group these items but having some problems.

I set the Property grouping in the VM to begin with and then added a GroupStyle.

C#:

ListCollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

XAML:

<ListView.GroupStyle>
    <GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                 <TextBlock Text="{Binding Path=Name}"/>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListView.GroupStyle>

However the list is now just the category names, no way to see the items themselves.

I'm not really understanding completely what is going on here. When I create a Template for the GroupStyle what am I really binding to? Are there other properties besides Name ?

I just added the GroupStyle to a ListView I has already created where I for example included a ItemTemplate. Is that something that is messing with the GroupStyle?

What if the Items in the list belong to another class and I wan't to group based on what instance of class they belong to (it has an ID). I would then have the group name as a property on this parent class. Is that possible?

PARTIAL SOLUTION:

Problem was with the style applied on the ListView. I have no idea what about the style was interefering.

FULL SOLUTION

I wasn't using a ItemsPresenter in my listbox ControlTemplate opting to use a Panel with IsItemsHost set to true. It seems ItemsPresenter must be used for GroupStyling to work correctly.

Naser Asadi
  • 1,153
  • 18
  • 35
Ingó Vals
  • 4,788
  • 14
  • 65
  • 113

1 Answers1

16

I think the error lies elsewhere in your code.

Usually, you expose a collection of Models on your ViewModel

namespace Derp
{
    public sealed class ViewModel
    {
      public ObservableCollection<Model> Items {get;set;}
      // initialization code not shown
    }

    public sealed class Model
    {
      public string GroupName {get;set;}
      public string ModelName {get;set;}
    }
}

In your View, you bind a CollectionViewSource to this collection:

<Window.DataContext>
    <ViewModel xmlns="clr-namespace:Derp" />
</Window.DataContext>
<Window.Resources>
    <CollectionViewSource
        Source="{Binding Items}"
        x:Key="GroupedItems">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription
                PropertyName="GroupName" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Window.Resources>

Next, we bind our list control to this CollectionViewSource (using a combo in this example):

<ComboBox
    ItemsSource="{Binding Source={StaticResource GroupedItems}}"
    DisplayMemberPath="ModelName">
    <ComboBox.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock
                        Text="{Binding Name}" />
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ComboBox.GroupStyle>
</ComboBox>

Where it can get confusing is that, within the GroupStyle, you aren't binding against your Model, you are binding against a collection of Models which is grouped on (in this case) the property "GroupName". The CollectionViewSource groups your Models into collections that extend CollectionViewGroup. These groups have a property called Name, which contains the common value on which your Models are grouped (the value of the GroupName property). So, in the HeaderTemplate, you are binding to CollectionViewGroup.Name.

Naser Asadi
  • 1,153
  • 18
  • 35
  • 1
    With the exception that I have the Items wrapped in a ListCollectionView class in the VM, I have almost the same code. And the problem is that it does work but it only shows the groups, not the items containes within. How should it show up as default? Should it be a expander or just a header? – Ingó Vals May 24 '11 at 13:43
  • @IngóVals: First, I'm not exactly sure what side effects are evident by having the CollectionViewSource in your VM; try moving it out as in the example and replacing it with an ObservableCollection in your VM. Next thing you need to do is turn up debug messages for databinding: http://i.imgur.com/UAxJO.png Next, re-run and check the output window and see what errors are there. –  May 24 '11 at 15:14
  • @Will: Having the CollectionViewSource outside doesn't change anything, even if I try changing it it's the same. Also the problem isn't binding, there are no binding errors or warnings. It seems like it is doing everything correctly. It's showing the correct names of the Categories and all. It's some sort of template/displaying problem, what is the default method that a list with a grouping is displayed? Where does the HeaderTemplate appear in relation to the data? – Ingó Vals May 24 '11 at 15:47
  • Note that I'm setting a ItemTemplate for the ListView before I set the groupStyle. It's like it's ignoring that template and thus not displaying any info about the item itself. – Ingó Vals May 24 '11 at 15:49
  • @IngóVals: Is the ItemTemplate a DataTemplate? Have you set the Type? Might have something to do with it... –  May 24 '11 at 16:01
  • Do you know what the ContainerStyle property of GroupStyle is for? – Ingó Vals May 24 '11 at 16:11
  • @IngóVals: Its the style applied to each [GroupItem](http://msdn.microsoft.com/en-us/library/system.windows.controls.groupitem.aspx) which is the visual container for each group. You shouldn't ever have to worry about or deal with it in normal use. –  May 24 '11 at 16:15
  • @IngóVals: Honestly, you are making this much more complex than needed. I think if you created a very simple prototype project and followed the guidelines I provided you would see it works pretty smoothly. Once you have your ListView working in the prototype, you can move the code back in your project, replacing what you already have. –  May 24 '11 at 16:19
  • Yeah I have found out that my ListView Style I'm using is interfering, I have no idea what about it doesn't work with grouping. – Ingó Vals May 24 '11 at 16:23
  • @IngóVals: Interesting. If you can repro it in an extremely simple example, ask a question about it. I'd like to see what's going on. –  May 24 '11 at 16:42
  • @Will I'll post it as a new question soon. I changed from that horrible stlye I had and created a UserControl but it has the same problem. Both the style and the UserControl have things in common that include overriding the ItemContainer on the ListBox, having a trigger on IsSelected and having that trigger make mor information about the item in List change from collapsed to visible in visibilit. Could any of these mess it up? – Ingó Vals Jun 01 '11 at 16:00
  • @Will Here, I've posted a new Question with relevent code http://stackoverflow.com/questions/6204455/wpf-groupstyle-not-working-correctly-because-of-style-and-or-modified-listbox – Ingó Vals Jun 01 '11 at 16:22