Getting CollectionViewSource groups to refresh RRS feed

  • Question

  • I've got a simple example of a CollectionViewSource that displays a collection of "Animals", grouped by the type of animal. There are two specific problems with it, as far as I'm concerned, and I'd like to understand if there's something that can be done to resolve either of these issues. They might both be the same issue, for all I know.

    The first issue occurs when adding a new element to the collection. Although it properly places it into the correct expander based on the group type, it doesn't cause my Header to update. My Header is bound to the CollectionViewGroup, and I'm using the Name and ItemCount as the header for my expander. So, if I click the button to add a new Dog to the collection, the dog will show up where it belongs, but the header will not update to reflect the new count.

    The second issue is that if I programmatically change the type of an object, it doesn't update the collections. I would expect that if I change an animal from a Dog to a Cat, then the item should be moved into the Cat expander. Instead, the object doesn't move.

    Can anyone give me an idea of this sort of thing is possible, and what I need to do to get it working?

    I wish I could attach a project, but I guess I'll just have to paste the source code below. The code is in a xaml file and its corresponding .cs file. The application runs just fine, so if you like you can create a new WPF app, and paste in these contents for the MainWindow.xaml and MainWindow.xaml.cs (this assumes the project is named "WpfApplication1".

          Source="{Binding Animals}">
              PropertyName="AnimalType" />
          x:Key="groupHeaderConverter" />
          TargetType="{x:Type Expander}">
            Value="{Binding Converter={StaticResource groupHeaderConverter}}" />
            Content="Click to Add a new Dog"
            Content="Click to Change a Dog into a Cat"
            ItemsSource="{Binding Source={StaticResource animalsSource}}">
                    Content="{Binding Name}"></Label>
                    Content="{Binding AnimalType}"></Label>
                    TargetType="{x:Type GroupItem}">
                          TargetType="{x:Type GroupItem}">
                            Style="{StaticResource groupHeader}">
                              Margin="20 0 0 0" />


    using System;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Data;
    namespace WpfApplication1
      /// <summary>
      /// Interaction logic for MainWindow.xaml
      /// </summary>
      public partial class MainWindow : Window
        public MainWindow()
          Animals = new ObservableCollection<Animal>();
          Animals.Add( new Animal( "Doggy", AnimalType.Dog ) );
          Animals.Add( new Animal( "Kitty", AnimalType.Cat ) );
          Animals.Add( new Animal( "Birdy", AnimalType.Bird ) );
          Animals.Add( new Animal( "Fishy", AnimalType.Fish ) );
          Animals.Add( new Animal( "Mousey", AnimalType.Mouse ) );
          this.DataContext = this;
        public ObservableCollection<Animal> Animals
        private void Button_Click( object sender, RoutedEventArgs e )
          Animals.Add( new Animal( string.Format( "Puppy #{0}", new Random().Next( 1, 1000 ).ToString() ), AnimalType.Dog ) );
        private void Button_Click_1( object sender, RoutedEventArgs e )
          foreach ( var animal in this.Animals ) {
            if ( animal.AnimalType == AnimalType.Dog ) {
              animal.AnimalType = AnimalType.Cat;
      public class Animal : DependencyObject
        public Animal( string name, AnimalType animalType )
          Name = name;
          AnimalType = animalType;
        public string Name
          get { return (string)this.GetValue( NameProperty ); }
          set { this.SetValue( NameProperty, value ); }
        public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
          "Name", typeof( string ), typeof( Animal ), new PropertyMetadata( "" ) );
        public AnimalType AnimalType
          get { return (AnimalType)this.GetValue( AnimalTypeProperty ); }
          set { this.SetValue( AnimalTypeProperty, value ); }
        public static readonly DependencyProperty AnimalTypeProperty = DependencyProperty.Register(
          "AnimalType", typeof( AnimalType ), typeof( Animal ), new PropertyMetadata() );
      public enum AnimalType
        Cat, Dog, Fish, Mouse, Bird
      public class GroupHeaderConverter : IValueConverter
        public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
          var cvg = value as CollectionViewGroup;
          if ( cvg == null )
            return string.Empty;
            return string.Format( "{0} ({1})", cvg.Name, cvg.ItemCount );
        public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
          throw new NotImplementedException();

    Thanks for any advice.


    Wednesday, February 3, 2010 10:20 PM


  • Ultimately found this project, which demonstrates the desired functionality:
    • Marked as answer by Dan Goyette Thursday, February 4, 2010 3:43 PM
    Thursday, February 4, 2010 3:43 PM