wpf 向“System.Windows.Controls.ItemCollection”类型的集合添加值引发异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22834622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add value to collection of type 'System.Windows.Controls.ItemCollection' threw an exception
提问by Ben
I'm having a problem with my WPF application, and i have no idea why. I'm far from an expert with XAML, and I don't understand this error, or even what part of the code is throwing the error.
我的 WPF 应用程序有问题,我不知道为什么。我远不是 XAML 的专家,我不明白这个错误,甚至不明白代码的哪一部分引发了错误。
I have the following view:
我有以下观点:
<DataGrid BorderThickness="0" Width="Auto" AutoGenerateColumns="False" AlternationCount="2"
IsSynchronizedWithCurrentItem="True" AutomationProperties.AutomationId="PositionSummaryGrid"
ItemsSource="{Binding Path=BOEList}" RowDetailsVisibilityMode="VisibleWhenSelected">
<DataGrid.Columns>
<DataGridTextColumn Header="BOE Reference" Binding="{Binding Path=Reference}"/>
<DataGridTextColumn Header="Account No" Binding="{Binding Path=AccountNo}"/>
<DataGridTextColumn Header="LBL Invoice No" Binding="{Binding Path=InvoiceNo}"/>
<DataGridTextColumn Header="Date Raised" Binding="{Binding Path=DateRaised}"/>
<DataGridTextColumn Header="Value" Binding="{Binding Converter={StaticResource currencyConverter}, Path=Value}" Width="85"/>
<DataGridTextColumn Header="Bank Charges" Binding="{Binding Converter={StaticResource currencyConverter}, Path=BankCharges}" Width="85"/>
<DataGridTextColumn Header="Payment Due" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentDue}" Width="85"/>
<DataGridTextColumn Header="Description" Binding="{Binding Path=Description}" Width="auto"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Which is styled using the following:
使用以下样式进行样式设置:
<Style x:Key="DataGridScrollViewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Focusable="false">
<Border CornerRadius="4" Background="{StaticResource DefaultedBorderBrush}" Padding="4" Margin="0,4,0,4">
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"/>
</Border>
</ScrollViewer>
<ScrollContentPresenter Name="PART_ScrollContentPresenter" KeyboardNavigation.DirectionalNavigation="Local"/>
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridColumnHeaderGripper" TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="18"/>
<Setter Property="Background" Value="#404040"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridColumnHeader}" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border Name="HeaderBorder" BorderThickness="0,1,0,1" BorderBrush="{x:Null}" Background="{x:Null}" Padding="2,0,2,0">
<ContentPresenter Name="HeaderContent" Margin="0,0,0,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource DataGridColumnHeaderGripper}" Foreground="#FFFFFFFF" Background="{x:Null}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
<Setter Property="Foreground" TargetName="PART_HeaderGripper" Value="#FFFCFCFC"/>
<Setter Property="Background" TargetName="HeaderBorder" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderContent" Property="Margin" Value="1,1,0,0"/>
<Setter Property="Foreground" TargetName="PART_HeaderGripper" Value="#FFE0E0E0"/>
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
<Setter Property="Background" TargetName="HeaderBorder" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGrid}" TargetType="{x:Type DataGrid}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="GridLinesVisibility" Value="None"/>
<Setter Property="SelectionMode" Value="Extended"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Name="Border" BorderThickness="1" BorderBrush="{x:Null}" Background="{x:Null}">
<ScrollViewer Style="{DynamicResource DataGridScrollViewer}" Foreground="#FFFFFFFF">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="#AAAAAA"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="#000000"/>
<Setter Property="DetailsVisibility" Value="Collapsed"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true" CornerRadius="4" Margin="0,4,0,0">
<SelectiveScrollingGrid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<DataGridDetailsPresenter SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
Grid.Column="1" Grid.Row="1"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Grid.RowSpan="2"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}"/>
</SelectiveScrollingGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" TargetName="Border" Value="#A5FFFFFF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" TargetName="Border" Value="#01FFFFFF"></Setter>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Border" Value="#99B4C6"/>
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Border" Value="#c5d7e5"/>
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Rectangle Fill="White" Opacity="0"></Rectangle>
<ContentPresenter HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The ViewModel is:
视图模型是:
public class BoeListViewModel : Screen
{
#region Fields
private BOEManager _Manager;
private ObservableCollection<BOE> _boeList;
#endregion
#region Properties
public ObservableCollection<BOE> BOEList
{
get { return _boeList; }
set
{
_boeList = value;
NotifyOfPropertyChange(() => BOEList);
}
}
public string Header
{
get { return "CURRENT BOES"; }
}
#endregion
#region Constructor
public BoeListViewModel()
{
this.DisplayName = "Current BOEs";
_Manager = IoC.Get<BOEManager>();
BOEList = _Manager.load();
}
#endregion
The BOE Model is a simple collection of properties including:
BOE 模型是一个简单的属性集合,包括:
public ObservableCollection<Payment> Payments
{
get { return _payments; }
set
{
if (value != _payments)
{
_payments = value;
NotifyOfPropertyChange(() => Payments);
}
}
}
With payment again a simple collection of Properties (this is just prototyping).
再次支付一个简单的属性集合(这只是原型设计)。
Exception appears to happen inside Caliburn Micro's OnStartup()method, but I'm not 100% sure about that. and it is:
异常似乎发生在 Caliburn Micro 的OnStartup()方法中,但我不是 100% 确定这一点。它是:
System.Windows.Markup.XamlParseException occurred
HResult=-2146233087
Message=Add value to collection of type 'System.Windows.Controls.ItemCollection' threw an exception.
Source=PresentationFramework
LineNumber=0
LinePosition=0
StackTrace:
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.UIElement.UpdateLayout()
at System.Windows.Interop.HwndSource.SetLayoutSize()
at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
at System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
at System.Windows.Window.SetRootVisual()
at System.Windows.Window.SetRootVisualAndUpdateSTC()
at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
at System.Windows.Window.CreateSourceWindowDuringShow()
at System.Windows.Window.SafeCreateWindowDuringShow()
at System.Windows.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.Show()
at Caliburn.Micro.WindowManager.ShowWindow(Object rootModel, Object context, IDictionary`2 settings) in c:\Users\Rob\Documents\CodePlex\caliburnmicro\src\Caliburn.Micro.WPF\WindowManager.cs:line 75
InnerException: System.InvalidOperationException
HResult=-2146233079
Message=Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
Source=PresentationFramework
StackTrace:
at System.Windows.Controls.ItemCollection.CheckIsUsingInnerView()
at System.Windows.Controls.ItemCollection.Add(Object newItem)
at System.Xaml.Schema.XamlTypeInvoker.AddToCollection(Object instance, Object item)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.Add(Object collection, XamlType collectionType, Object value, XamlType valueXamlType)
InnerException:
sorry for the code dump, but I have no real clue what part of this code is causing the error, as it just throws the error without a location, I'm fairly certain is has to do with the RowDetails, as without the RowDetailsthis works without an issue, however I cannot for the life of me work out what is going on.
抱歉代码转储,但我不知道这段代码的哪一部分导致了错误,因为它只是在没有位置的情况下抛出错误,我相当肯定这与RowDetails,因为没有RowDetailsthis 工作没有一个问题,但是我一生都无法弄清楚发生了什么。
Also, if someone could let me know how to track down these kind of error?
另外,如果有人能让我知道如何追踪这些错误?
EDIT:
编辑:
Two things.
两件事情。
Removing the line RowDetailsVisibilityMode="VisibleWhenSelected"allows the application to run without an exception, however obviously then the details row is never shown.
删除该行RowDetailsVisibilityMode="VisibleWhenSelected"允许应用程序无异常地运行,但很明显,详细信息行永远不会显示。
Secondly, commenting out the DataGridDetailsPresenterinside the DataGrid row style also has the same effect of allowing this to run, so it must be something with that, however that code is taken straight from Microsoft examples.
其次,注释掉DataGridDetailsPresenterDataGrid 行样式的内部也具有允许此运行的相同效果,因此它必须与此相关,但是该代码直接取自 Microsoft 示例。
采纳答案by Ben
The Problem was this:
问题是这样的:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
Apparently you cannot define a datatemplate for a collection directly in the xaml page, as soon as i moved the datagrid into a style sheet and bound it using ItemTemplate it worked.
显然,您不能直接在 xaml 页面中为集合定义数据模板,只要我将数据网格移动到样式表中并使用 ItemTemplate 绑定它就可以了。
<ItemsControl ItemsSource="{Binding Payments}" ItemTemplate="{StaticResource PaymentItemTemplate}"/>
I assume the itemcollection it was complaining about was the one containing the views controls, and that it has issues creating multiple elements inside a single row at runtime.
我假设它抱怨的 itemcollection 是包含视图控件的 itemcollection,并且它在运行时在单行内创建多个元素时存在问题。
回答by Chrille
Your problem is that you do not define your columns in a proper way.
您的问题是您没有以正确的方式定义列。
Add a DataGrid.Columnstag
添加DataGrid.Columns标记
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGrid.Columns>
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>

