Search code examples
wpfdata-bindingdatagridcollectionviewcollectionviewsource

How to bind CollectionViewSource to DataGrid


I have a datagrid and want to bind its item source as CollectionViewSource which has the source of List. But binding is not working. Please check my code in below. Note that i dont want to use ObservableCollection because of virtualization problem while grouping.

 <UserControl.Resources>
   <CollectionViewSource x:Key="weightItemCollection" Source="{Binding Path=LoadCaseWeightItems}" >
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="LocalizedGroupName"/>
        </CollectionViewSource.SortDescriptions>
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="LocalizedGroupName"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>

<DataGrid  x:Name="customLoadCaseGrid"
              ItemsSource="{Binding Source={StaticResource weightItemCollection}}" />

User Control code

public partial class WeightItem : INotifyPropertyChanged
   {
   List<WeightItemData> loadCaseWeightItems;
  public List<WeightItemData> LoadCaseWeightItems { get { return loadCaseWeightItems; } set { loadCaseWeightItems = value; OnPropertyChanged(nameof(LoadCaseWeightItems)); } }
  public event PropertyChangedEventHandler PropertyChanged;
  
   public WeightItem()
    {
        InitializeComponent();
        loadCaseWeightItems = new List<WeightItemData>();
        //Here i add items to loadCaseWeightItems 
    }

  
  
  protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    
    }

Solution

  • This should work:

    <UserControl.Resources>
        <CollectionViewSource x:Key="weightItemCollection"
                              Source="{Binding Path=LoadCaseWeightItems,RelativeSource={RelativeSource AncestorType=UserControl}}" >
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="LocalizedGroupName"/>
             </CollectionViewSource.SortDescriptions>
             <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="LocalizedGroupName"/>
             </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </UserControl.Resources>
    <Grid>
        <DataGrid x:Name="customLoadCaseGrid" ItemsSource="{Binding Source={StaticResource weightItemCollection}}" />
    </Grid>
    

    You may also set the Source programmatically:

    public WeightItem()
    {
        InitializeComponent();
        loadCaseWeightItems = ...;
    
        ((CollectionViewSource)Resources["weightItemCollection"]).Source = loadCaseWeightItems;
    }