Question

I am newbie and am confused of some syntax of ListBox.GroupStyle. The code:

    <Window x:Class="testCollectionViewSource.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <CollectionViewSource x:Key="CVS" Source="{Binding Path=Cs}">
                <CollectionViewSource.GroupDescriptions>
                    <PropertyGroupDescription PropertyName="B" />
                </CollectionViewSource.GroupDescriptions>
            </CollectionViewSource>
        </Window.Resources>
        <Grid>
            <ListBox ItemsSource="{Binding Source={StaticResource CVS}}">

                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock   Text="{Binding S}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>

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

            </ListBox>

        </Grid>
    </Window>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Cs = new ObservableCollection<C>();
        Cs.Add(new C(true, "1"));
        Cs.Add(new C(false, "2"));
        Cs.Add(new C(true, "3"));
        Cs.Add(new C(false, "4"));
        DataContext = this;
    }

    public ObservableCollection<C> Cs { get; set; }
}

public class C
{
    public C(bool b, string s)
    {
        B = b;
        S = s;
    }
    public bool B { get; set; }
    public string S { get; set; }
}

So my question is why only when {Binding Name} does the header displays "True" or "False", and why {Binding B} not work? What does "Name" mean, since the Class C does not have such property.

Was it helpful?

Solution

If you inspect the application using Snoop, you'll realize the DataContext of your TextBlock and it's ancestors up to the GroupItem is an object of type MS.Internal.Data.CollectionViewGroupInternal, which contains a Name property:

enter image description here

This is why {Binding Name} works in there, while {Binding B} does not.

OTHER TIPS

Name is a Property of CollectionViewGroup Class which is the default DataContext for collections grouped by CollectionView based on GroupDescriptions.

When you use grouping DataContext of each group will be set to an instance of CollectionViewGroup which, apart from Items, stores some information about the group itself. Name will represent the value under which items have been grouped. So in your case when you do:

<PropertyGroupDescription PropertyName="B" />

it means that you create different groups for different values of B and because it's of a Boolean type it means that there are only 2 groups possible. One for B == true and second for B == false hence text in your header

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top