Wpf 自动滚动到我的上一个ListView项目添加导致InvalidoperationException
我有这个收藏:Wpf 自动滚动到我的上一个ListView项目添加导致InvalidoperationException,wpf,listview,Wpf,Listview,我有这个收藏: public ObservableCollection<MyData> files { get; set; } 当新项目添加到我的列表视图中时: private void files_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { Application.Current.Dispa
public ObservableCollection<MyData> files { get; set; }
当新项目添加到我的列表视图中时:
private void files_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
listView.ItemsSource = files;
listView.SelectedIndex = listView.Items.Count - 1;
listView.ScrollIntoView(listView.SelectedItem);
}
}));
}
我这样做的原因是,我想看到文件添加和自动滚动上一个添加的项目
因此结果是invalidoOperationException
:
ItemsControl与其items源不一致。看内在
更多信息请参见例外
更新
内部异常:
{“开发人员信息”(使用文本可视化工具阅读此信息):\r\n引发此异常,因为名为“ListView”的控件“System.Windows.Controls.ListView Items.Count:6”的生成器已接收到CollectionChanged事件序列,这些事件序列与Items集合的当前状态不一致。检测到以下差异:\r\n累计计数2与实际计数不同6.[累计计数为(上次重置时的计数+#添加-#自上次重置后删除)。]\r\n\r\n以下一个或多个源可能引发了错误的事件:\r\n System.Windows.Controls.ItemContainerGenerator\r\n System.Windows.Controls.ItemCollection\r\n System.Windows.Data.ListCollectionView\r\n System.Collections.ObjectModel.ObservableCollection`1[应用程序名称,版本=2.0.0.0,区域性=中性,PublicKeyToken=null]\r\n(星号源被认为更可能是问题的原因。)\r\n\r\n最常见的原因是(a)在不引发相应事件的情况下更改集合或其计数,以及(b)使用不正确的索引或项参数引发事件。\r\n\r\n异常的堆栈跟踪描述了不一致是如何检测到的,而不是如何发生的。若要获得更及时的异常,请将生成器上的附加属性“PresentationTraceSources.TraceLevel”设置为值“High”,然后重新运行该方案。一种方法是从即时窗口运行类似于以下命令的命令:\n System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator,System.Diagnostics.PresentationTraceLevel.High)\r\n这会导致检测逻辑在每个CollectionChanged事件后运行,因此会降低应用程序的速度。\r\n“}
发生异常的原因是此行(删除此行时一切正常):
尝试将滚动到视图与设置当前所选项目分开
连接ListView SelectionChanged=“OnSelectionChanged”并按如下方式实现:
private void OnSelectionChanged( object sender, SelectionChangedEventArgs e )
{
Selector selector = sender as Selector;
ListView listView = selector as ListView;
if ( listView != null && selector.SelectedItem != null )
{
listView.ScrollIntoView( selector.SelectedItem );
}
}
对于ObservableCollection.CollectionChanged:
private void OnCollectionChanged( object sender,
NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs )
{
if ( notifyCollectionChangedEventArgs.NewItems != null )
{
var newItem = notifyCollectionChangedEventArgs.NewItems.Cast<MyData>().LastOrDefault();
if ( newItem != null )
{
listView.SelectedItem = newItem;
}
}
}
CollectionChanged上的私有void(对象发送方,
NotifyCollectionChangedEventArgs NotifyCollectionChangedEventArgs)
{
if(notifyCollectionChangedEventArgs.NewItems!=null)
{
var newItem=notifyCollectionChangedEventArgs.NewItems.Cast().LastOrDefault();
if(newItem!=null)
{
listView.SelectedItem=newItem;
}
}
}
我不知道为什么每次集合更改时都要更改listView.ItemsSource。似乎您通常会在新建或设置ObservableCollection时这样做。我想您指的是WPF。如果是,请编辑您的帖子并添加适当的标签。是的,这是一个打字错误,已更新。内部异常是什么?哪里出现异常?请查看我的更新。
private void OnSelectionChanged( object sender, SelectionChangedEventArgs e )
{
Selector selector = sender as Selector;
ListView listView = selector as ListView;
if ( listView != null && selector.SelectedItem != null )
{
listView.ScrollIntoView( selector.SelectedItem );
}
}
private void OnCollectionChanged( object sender,
NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs )
{
if ( notifyCollectionChangedEventArgs.NewItems != null )
{
var newItem = notifyCollectionChangedEventArgs.NewItems.Cast<MyData>().LastOrDefault();
if ( newItem != null )
{
listView.SelectedItem = newItem;
}
}
}