由于绑定错误,WPF DataGrid 分组不显示

发布于 2024-09-25 07:34:32 字数 10523 浏览 1 评论 0原文

我收到此错误消息:

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 代码。

我的绑定有什么问题吗?

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>

更新:为什么绑定不适用于下面的“Schoolclasscode”?

错误:System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“CollectionViewGroupInternal”(HashCode=15576908) 上找不到“SchoolclassCode”属性。 BindingExpression:Path=学校班级代码; DataItem='CollectionViewGroupInternal'(哈希码=15576908);目标元素是“TextBlock”(名称=“”);目标属性是“Text”(类型“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>

我现在已将绑定更改为当前数据上下文以查看其中的内容:

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

您在 Expander Text 中看到类名吗?我如何从现在开始访问我的 ObservableCollection?

替代文本

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

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

Update: Why is the Binding not working for "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')

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

I have changed the binding now to the current datacontext to see whats in 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 at the Expander Text ? How can I access my ObservableCollection from this point?

alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦明 2024-10-02 07:34:32

首先,如果我有足够的观点可以这样做,我会将其作为对 Elisa 关于 CollectionViewGroup.Name 的决议的评论。我第一次尝试使用分组时也遇到了这个错误。

Name 属性的population(来自下面的源属性)是通过使用以下项设置的:
_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>

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

First of all, I would have made this a comment on Elisa's resolution about CollectionViewGroup.Name - if I had points enough to do so. Got this error too on my first attempt to use grouping.

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

(More than one PropertyGroupDescription added to one view causes additional group styles to be applied for each and their corresponding Name properties populated accordingly.)

To clarify the Elisa's resolution - just change the binding as below:

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

Hope this saves could save time for somebody else.

一腔孤↑勇 2024-10-02 07:34:32

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,它仍然是不允许的。

A CollectionViewSource takes a collection and wraps it with an ICollectionView. However, You are binding directly to a ICollectionView, which it cannot wrap. Make your property in the model some raw collection type IEnumerable) and bind to it.

Here's the code to CollectionViewSource's 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 it specifically checks for a ICollectionView and disallows it. Even though ICollectionView is IEnumerable, it is still not allowed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文