WPF CollectionViewSource Grouping
Asked Answered
K

2

8

I'm using a CollectionViewSource to group my data. In my data, I have Property1 and Property2 that I'm needing to group on.

The only stipulation is that I don't want sub-groups of another group. So, when I group by these two properties, I don't want to have it so that Property2 because a subgroup of Property1's group.

The reason why I want this is because I need to have a header that shows the following information:

Header:

<TextBlock.Text>
  <MultiBinding StringFormat="Property1: {0}, Property2: {1}">
    <Binding Path="Property1"/>
    <Binding Path="Property2"/>
  </MultiBinding>
</TextBlock.Text>

I've tried this with my CollectionViewSource but was not able to "combine" the group and subgroup together:

<CollectionViewSource x:Key="myKey" Source="{Binding myDataSource}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="Property1" />
    <PropertyGroupDescription PropertyName="Property2" />
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

Is it possible to group two properties together? Something like below?

<CollectionViewSource x:Key="myKey" Source="{Binding myDataSource}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="Property1,Property2" />
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
Killiecrankie answered 8/10, 2010 at 20:47 Comment(0)
A
27

Instead of creating another new property in your object actually you can also have some tricks on the converter. Dot ('.') is pass the whole object into you converter. So you can do whatever logic algorithm over there instead of creating a new property in your original object.

<CollectionViewSource x:Key="myKey" Source="{Binding myDataSource}">
    <CollectionViewSource.GroupDescriptions>
         <PropertyGroupDescription PropertyName="." 
                     Converter="{StaticResource Property1AndProperty2}" />
     </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

At your converter something like this:

public class WidthAndHeightMixer : IValueConverter
{
      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
      {
            if (value is YourObject)
            {
                  return (value as YourObject).Property1 + (value as Inventory).Property2
            }
      }
      ......
Acidulous answered 14/4, 2011 at 10:35 Comment(2)
nice, that's exactly what I was looking forKilliecrankie
This is a great tip, honestly.Maiden
U
4

You could combine the properties into one property on your data object. For instance:

public class Person
{
    public Person()
    {
        IsActive = true;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Boolean IsActive { get; set; }
    public string LastNameIsActive
    {
        get { return LastName + IsActive.ToString(); }
    }
}
<Grid.Resources>
    <CollectionViewSource  x:Key="view" Source="{StaticResource persons}">
        <CollectionViewSource.SortDescriptions>
            <cm:SortDescription PropertyName="LastName" Direction="Ascending"/>
            <cm:SortDescription PropertyName="IsActive" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="LastNameIsActive"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Grid.Resources>
<ListView  ItemsSource="{Binding Source={StaticResource view}}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}"/>
            <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}"/>
        </GridView>
    </ListView.View>
    <ListView.GroupStyle>
        <GroupStyle >
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Background="Gray" DataContext="{Binding Items}">
                        <TextBlock.Text>
                            <MultiBinding  StringFormat="Is Active: {0} Last Name: {1}">
                                <Binding Path="IsActive"/>
                                <Binding Path="LastName"/>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ListView.GroupStyle>
</ListView>

Underlie answered 3/3, 2011 at 16:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.