WPF DataGrid分组由于绑定错误而未显示

时间:2010-09-29 21:34:17

标签: wpf mvvm datagrid grouping

我收到此错误消息:

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')

以下是重要的Xaml + 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");
            }
        }
    }

查看:

    <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>

更新:为什么Binding不能用于下面的“Schoolclasscode”?

错误: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>

我现在已将绑定更改为当前的datacontext以查看其中的内容:

  <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>

您是否在扩展器文本中看到了班级名称?如何从这一点访问我的ObservableCollection?

alt text

2 个答案:

答案 0 :(得分:8)

首先,我会对Elisa关于CollectionViewGroup.Name的决议做出评论 - 如果我有足够的分数这样做的话。我第一次尝试使用分组时也遇到了这个错误。

Name属性的种群,来自下方的source属性,使用以下方式设置: _materialList.GroupDescriptions.Add(new PropertyGroupDescription("Schoolclasscode"));

(在一个视图中添加了多个PropertyGroupDescription会导致为每个视图应用其他组样式,并相应地填充相应的Name属性。)

澄清Elisa的决议 - 只需更改绑定如下:

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

希望这些节省可以节省其他人的时间。

答案 1 :(得分:2)

CollectionViewSource接收一个集合并用ICollectionView包装它。但是,您直接绑定到ICollectionView,它无法包装。在模型中使您的属性成为一些原始集合类型IEnumerable)并绑定到它。

这是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);
}

您可以看到它专门检查ICollectionView并禁止它。即使ICollectionView IEnumerable,它仍然是不允许的。