locked
Wrapping groups in ListView similar to People App RRS feed

  • Question

  • I am trying to create a list that wraps similar to the list of people in the People App. I can create a list view that wraps as there are tons of sample. I can also build a list that wraps groups but this has a very unpleasant effect where the first group determines the size over ever other group. This can either create a lot of empty space when the groups are smaller than the first group. Or it will truncate groups that are larger than the first.

      I cannot find a sample that whit a list view that wraps grouped data and does not use the same ItemsPanelTemplate.

    Saturday, November 17, 2012 9:53 PM

Answers

  • The default way also fails to virtualise...

    If you're okay with getting your hands a little dirty, There is a "way" of doing it - well, I've done something similar. But it requires quite a bit of manual wiring, and it's not neat. Basically, you need to use flat lists.

    1) Group the data into a grouped list

    2) Return all that data into a FLAT list in order, but including the group headers in the right places. To do this, the group header shall have to be some dummy item of the same data type that the list is. That means the list data type will need at least two string fields. Assign the group "key" / header text too one of those fields, and then assign a dummy "identifying" string too the other. (Basically, so you can identify that this is not a real key, but a group header).

    3) Your XAML datatemplate for your grid view will now include both the group key header template, and the data item template - as children of a parent grid. You will write a ValueConverter that looks at the data bound to each grid, identifies whether it's a real data item or a dummy group header, and show hide part of the data template. You use the converter parameter to signify if this grid is the data item template or the group key template.

    <DataTemplate ...>
       <Grid ...>
            <Grid x:Name="ItemTemplate" Visibilty="{Binding  Converter={StaticResource myVisConverter, ConverterParameter=true}">
                 ...
            </Grid>

            <Grid x:Name="GroupHeaderTemplate" Visibilty="{Binding  Converter={StaticResource myVisConverter, ConverterParameter=false}" />
                 ...
            </Grid>
        </Grid>
    </DataTemplate>

    4) Voila, it works. But ah, you want semantic zoom too...

    5) Manually hook up semantic zoom events using "ScrollIntoView" method on SemanticViewChanged event (or something similar)

    Now, I'm not saying I recommend this method. But, it works. And you get to keep virtualisation. Obviously, your data item and your group header will probably have to be the same size, or direct multiples of each other, because that's just how grid views work. They're grids :P


    • Edited by John Westlake Sunday, November 18, 2012 1:51 AM
    • Proposed as answer by Suny_Choudhary Tuesday, November 20, 2012 6:05 PM
    • Marked as answer by sperniner Tuesday, November 20, 2012 6:25 PM
    Sunday, November 18, 2012 1:48 AM

All replies

  • The default way also fails to virtualise...

    If you're okay with getting your hands a little dirty, There is a "way" of doing it - well, I've done something similar. But it requires quite a bit of manual wiring, and it's not neat. Basically, you need to use flat lists.

    1) Group the data into a grouped list

    2) Return all that data into a FLAT list in order, but including the group headers in the right places. To do this, the group header shall have to be some dummy item of the same data type that the list is. That means the list data type will need at least two string fields. Assign the group "key" / header text too one of those fields, and then assign a dummy "identifying" string too the other. (Basically, so you can identify that this is not a real key, but a group header).

    3) Your XAML datatemplate for your grid view will now include both the group key header template, and the data item template - as children of a parent grid. You will write a ValueConverter that looks at the data bound to each grid, identifies whether it's a real data item or a dummy group header, and show hide part of the data template. You use the converter parameter to signify if this grid is the data item template or the group key template.

    <DataTemplate ...>
       <Grid ...>
            <Grid x:Name="ItemTemplate" Visibilty="{Binding  Converter={StaticResource myVisConverter, ConverterParameter=true}">
                 ...
            </Grid>

            <Grid x:Name="GroupHeaderTemplate" Visibilty="{Binding  Converter={StaticResource myVisConverter, ConverterParameter=false}" />
                 ...
            </Grid>
        </Grid>
    </DataTemplate>

    4) Voila, it works. But ah, you want semantic zoom too...

    5) Manually hook up semantic zoom events using "ScrollIntoView" method on SemanticViewChanged event (or something similar)

    Now, I'm not saying I recommend this method. But, it works. And you get to keep virtualisation. Obviously, your data item and your group header will probably have to be the same size, or direct multiples of each other, because that's just how grid views work. They're grids :P


    • Edited by John Westlake Sunday, November 18, 2012 1:51 AM
    • Proposed as answer by Suny_Choudhary Tuesday, November 20, 2012 6:05 PM
    • Marked as answer by sperniner Tuesday, November 20, 2012 6:25 PM
    Sunday, November 18, 2012 1:48 AM
  • I was afraid that this was going to be the answer.  I don't think I am going to hack this in. I'll find another way to display the data. :(
    thanks for the reply!
    • Edited by sperniner Tuesday, November 20, 2012 6:32 PM
    Tuesday, November 20, 2012 6:25 PM