我收到此错误消息:
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?
答案 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,它仍然是不允许的。