WPF DataGrid Grouping not showing due to binding error

I get this error message:

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='System.Windows.Data.ListCollectionView' BindingExpression:Path=MaterialList; DataItem='MaterialBrowserListViewModel' (HashCode=24964411); target element is 'CollectionViewSource' (HashCode=36518048); target property is 'Source' (type 'Object') 

The following is the important Xaml + ViewModel code.

What is wrong with my binding?

ViewModel:

 public class MaterialBrowserListViewModel : ViewModelBase { private IDocumentRepository _docRepo; private ICollectionView _materialList; public MaterialBrowserListViewModel() { _docRepo= new DocumentRepository(); MaterialList = CollectionViewSource.GetDefaultView(_docRepo.GetMaterialList()); //_materialList.GroupDescriptions.Add(new PropertyGroupDescription("Schoolclasscode")); } public ICollectionView MaterialList { get { return _materialList; } set { _materialList = value; this.RaisePropertyChanged("MaterialList"); } } } 

VIEW:

  <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!--<ResourceDictionary Source="Themes\DataGrid.Generic.xaml"/>--> </ResourceDictionary.MergedDictionaries> <CollectionViewSource Source="{Binding MaterialList}" x:Key="groupedView"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="DocumentName"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> <!-- GroupHeaderStyle --> <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True" Background="Blue" Foreground="White"> <Expander.Header> <TextBlock Text="{Binding Name.Name}"/> </Expander.Header> <ItemsPresenter /> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> </UserControl.Resources> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" Background="AliceBlue"> <Grid.RowDefinitions> <RowDefinition Height="35" /> <RowDefinition Height="25"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Margin="0,0,0,10" Grid.Row="0" Orientation="Horizontal"> <Button Content="Open" /> <Button Content="Delete" /> <Button Content="Export" /> <Button Content="Clear Filter" /> </StackPanel> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding ElementName=col0, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=col1, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=col2, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=col3, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=col4, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=col5, Path=ActualWidth}" /> </Grid.ColumnDefinitions> <DatePicker Grid.Column="0" /> <TextBox Grid.Column="1" /> <ComboBox Grid.Column="2" /> <ComboBox Grid.Column="3" /> <TextBox Grid.Column="4" /> </Grid> <DataGrid CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource groupedView}}" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="15" x:Name="MaterialGrid" IsSynchronizedWithCurrentItem="True" AlternatingRowBackground="AliceBlue" VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" HeadersVisibility="Column" CanUserResizeColumns="True" CanUserSortColumns="True" IsReadOnly="True" > <DataGrid.GroupStyle> <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"> <GroupStyle.Panel> <ItemsPanelTemplate> <DataGridRowsPresenter/> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Schoolday}" x:Name="col0" Header="Date" /> <DataGridTextColumn Binding="{Binding Period}" x:Name="col1" Header="Period" /> <DataGridTextColumn Binding="{Binding SchoolclassCode}" x:Name="col2" Header="Class code" /> <DataGridTextColumn Binding="{Binding DocumentName}" x:Name="col3" Header="Document name" /> <DataGridTextColumn Binding="{Binding Keywords}" x:Name="col4" Header="Keywords" /> <DataGridTextColumn Binding="{Binding DocumentId}" x:Name="col5" Header="Doc Id" /> </DataGrid.Columns> </DataGrid> </Grid> </UserControl> 

Refresh . Why does the binding not work for the "Schoolclasscode" below?

Error: System.Windows.Data Error: 40 : BindingExpression path error: 'SchoolclassCode' property not found on 'object' ''CollectionViewGroupInternal' (HashCode=15576908)'. BindingExpression:Path=SchoolclassCode; DataItem='CollectionViewGroupInternal' (HashCode=15576908); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'SchoolclassCode' property not found on 'object' ''CollectionViewGroupInternal' (HashCode=15576908)'. BindingExpression:Path=SchoolclassCode; DataItem='CollectionViewGroupInternal' (HashCode=15576908); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

 <!-- GroupHeaderStyle --> <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True" Background="AliceBlue" Foreground="White"> <Expander.Header> <TextBlock Text="{Binding SchoolclassCode}"/> </Expander.Header> <ItemsPresenter /> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> 

Now I changed the binding to the current datacontext to see what's there:

  <DataGrid CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource ResourceKey=groupedView}}" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="15" x:Name="MaterialGrid" IsSynchronizedWithCurrentItem="True" AlternatingRowBackground="AliceBlue" VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" HeadersVisibility="Column" CanUserResizeColumns="True" CanUserSortColumns="True" IsReadOnly="True" > <DataGrid.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True"> <Expander.Header> <TextBlock Foreground="Black" Text="{Binding }"/> </Expander.Header> <ItemsPresenter /> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Schoolday}" x:Name="col0" Header="Date" /> <DataGridTextColumn Binding="{Binding Period}" x:Name="col1" Header="Period" /> <DataGridTextColumn Binding="{Binding SchoolclassCode}" x:Name="col2" Header="Class code" /> <DataGridTextColumn Binding="{Binding DocumentName}" x:Name="col3" Header="Document name" /> <DataGridTextColumn Binding="{Binding Keywords}" x:Name="col4" Width="*" Header="Keywords" /> <!--<DataGridTextColumn Binding="{Binding DocumentId}" x:Name="col5" Header="Doc Id" />--> </DataGrid.Columns> </DataGrid> 

Do you see the class name in the text Expander? How can I access my ObservableCollection from this point?

alt text

+6
wpf mvvm datagrid grouping
source share
2 answers

First of all, I would make a comment on Eliza’s resolution on CollectionViewGroup.Name - if I had enough points to do this. I got this error on my first attempt to use grouping.

The population of this Name property, from the source property below, is set using: _materialList.GroupDescriptions.Add(new PropertyGroupDescription("Schoolclasscode"));

(More than one PropertyGroupDescription added to one view forces you to add additional group styles for each and their corresponding Name properties.)

To clarify Eliza’s resolution, simply change the binding as shown below:

 <Expander IsExpanded="True" Background="AliceBlue" Foreground="White"> <Expander.Header> <TextBlock Text="{Binding Name}"/> </Expander.Header> <ItemsPresenter /> </Expander> 

Hope this saves, can save time for someone else.

+8
source share

Collection CollectionViewSource takes a collection and wraps it using ICollectionView. However, you bind directly to an ICollectionView that it cannot wrap. Make your property in the model the incorrect type of the IEnumerable collection) and bind to it.

Here is the code for CollectionViewSource IsSourceValid:

 private static bool IsSourceValid(object o) { if (((o != null) && !(o is IEnumerable)) && (!(o is IListSource) && !(o is DataSourceProvider))) { return false; } return !(o is ICollectionView); } 

You can see that it specifically checks the ICollectionView and disallows it. Although ICollectionView is IEnumerable, it is still not allowed.

+2
source share

All Articles