CollectionViewSource XAML

In an earlier blog I talked about how to filter a CollectionViewSource. This time around we are going to talk about how to create your CollectionViewSource Object in XAML and set the object up in XAML to group. This feature really comes in handy whenever you have a list you want to display and group it. You can change the group in code as well.

 

<Window.Resources>
    
    <CollectionViewSource Source="{Binding}" x:Key="cvs">
      <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Type" />
      </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
    
  </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition />
        </Grid.RowDefinitions>
      <ListBox Name="MyList" Grid.Row="0" ItemsSource="{Binding Source={StaticResource cvs}}"
                DisplayMemberPath="Name">
        <ListBox.GroupStyle>
          <x:Static Member="GroupStyle.Default" />
        </ListBox.GroupStyle>
      </ListBox>
       
    </Grid>

 

Here is the code behind

 

public partial class CollectionViewSource : System.Windows.Window
    {

        public CollectionViewSource()
        {
            InitializeComponent();

            Truck[] myValues = new Truck[4];

            myValues.SetValue(new Truck("Truck", "Red"), 0);
            myValues.SetValue(new Truck("Truck", "Blue"), 1);
            myValues.SetValue(new Truck("Car", "Blue"), 2);
            myValues.SetValue(new Truck("Car", "Red"), 3);

            this.DataContext = myValues;
      
        }

    }

    public class Truck
    {
        private string _type;
        private string _color;

        public Truck(string Type, string Color)
        {
            _type = Type;
            _color = Color;
        }

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }


        public string Color
        {
            get { return _color; }
            set { _color = value; }
        }

        public string Name
        {
            get { return string.Concat(this.Type, " ", this.Color); }
        }
    }

 

Screenshot #1

Screenshot #2 

Screenshot #3

 

sorry for the blurry pics 

 

 

As you can see the list is now grouped by the type of car (Truck and Car. Yes I know a truck is a type of car, I just wanted a quick example). You can change

<PropertyGroupDescription PropertyName="Type" /> So property name is Color and the list will be sorted by color. You can also do this in code. In my second screenshot I have a check box. If you click the check box it changes the grouping to be by color. The follow code allows you to do this.

 

private void ColorSort(Object sender, RoutedEventArgs args)
        {
            CollectionViewSource csv = (CollectionViewSource)FindResource("cvs");
            csv.GroupDescriptions.Clear();

            if (Sort.IsChecked == true)
            {
                PropertyGroupDescription colorGroup = new PropertyGroupDescription("Color");

                csv.GroupDescriptions.Add(colorGroup);
            }
                // Add default group back
            else
            {
                csv.GroupDescriptions.Clear();
                PropertyGroupDescription typeGroup = new PropertyGroupDescription("Type");

                csv.GroupDescriptions.Add(typeGroup);
            }
        }

 

Do you want more control over how the items look? This is easily done by changing just a few things in the xaml. The third screenshot from above shows a more custom look to the list. This is done by adding two resources and changing the list box binding a little. Here is what I changed. I have made the xaml I changed in the listbox bold and italic. You will notice that in the GroupItem template I bind the textblock to the "Name" path. The name is the groupdescription property name that is being grouped not the name property on my object.

 

<DataTemplate x:Key="GroupHeader">
      <TextBlock Background="BurlyWood" Text="{Binding Path=Name}"></TextBlock>
    </DataTemplate>

    <DataTemplate x:Key="GroupItem">
      <TextBlock Text="{Binding Path=Name}" Margin="0,0,0,10">
        <TextBlock.RenderTransform>
          <SkewTransform CenterX="0" CenterY="0" AngleX="0" AngleY="10" />
        </TextBlock.RenderTransform>
      </TextBlock>
    </DataTemplate>
<ListBox Name="MyList" Grid.Row="1" ItemsSource="{Binding Source={StaticResource cvs}}"
                ItemTemplate="{StaticResource GroupItem}">
        <ListBox.GroupStyle>
          <GroupStyle HeaderTemplate="{StaticResource GroupHeader}" />
        </ListBox.GroupStyle>
      </ListBox>

This entry was posted in WPF. Bookmark the permalink.

Leave a comment