C# WPF DataGrid未显示所有行

C# WPF DataGrid未显示所有行,c#,wpf,multithreading,datagrid,binding,C#,Wpf,Multithreading,Datagrid,Binding,我有一个绑定到WPF数据网格的ObservableCollection。ObservableCollection以异步方式填充和更新 DataGrid未显示正确的行数。每次运行应用程序时,都会显示不同数量的行,通常为7-8行,但有时仅显示一行。我在ListBox中得到了相同的behvaior,但在ComboBox中没有 我在ListBox和ItemsControl中得到了相同的行为,但在ComboBox中没有。组合框按预期正确显示所有18项 编辑 此类型的CollectionView不支持从不同

我有一个绑定到WPF数据网格的ObservableCollection。ObservableCollection以异步方式填充和更新

DataGrid未显示正确的行数。每次运行应用程序时,都会显示不同数量的行,通常为7-8行,但有时仅显示一行。我在ListBox中得到了相同的behvaior,但在ComboBox中没有

我在ListBox和ItemsControl中得到了相同的行为,但在ComboBox中没有。组合框按预期正确显示所有18项

编辑


此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection

我需要在这里做更多的侦查工作,因为我的假设是更新发生在同一个线程中。因此,正确显示前几个项目的原因是ViewModel能够在加载视图之前检索一些数据

使用此代码:
(注意DownloadedItem及其属性也必须使用INotifyPropertyChanged,如本例所示)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Collections.ObjectModel;
命名空间WpfApplication1
{
类下载:NotifyBase
{
公共虚拟可观察集合下载EditemCollection
{
获取{return\u DownloadedItemCollection;}
设置{u DownloadedItemCollection=value;OnPropertyChanged(System.Reflection.MethodBase.GetCurrentMethod().Name.Substring(4));/*OnPropertyChanged(“DownloadedItemCollection”);*/}
}private ObservableCollection\u DownloadedItemCollection;
}
}
公共类NotifyBase:INotifyPropertyChanged
{
#区域数据库
//宣布事件
公共虚拟事件System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
#端区
}
使用此代码:
(请注意,DownloadedItem及其属性也必须使用INotifyPropertyChanged,如本例所示)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Collections.ObjectModel;
命名空间WpfApplication1
{
类下载:NotifyBase
{
公共虚拟可观察集合下载EditemCollection
{
获取{return\u DownloadedItemCollection;}
设置{u DownloadedItemCollection=value;OnPropertyChanged(System.Reflection.MethodBase.GetCurrentMethod().Name.Substring(4));/*OnPropertyChanged(“DownloadedItemCollection”);*/}
}private ObservableCollection\u DownloadedItemCollection;
}
}
公共类NotifyBase:INotifyPropertyChanged
{
#区域数据库
//宣布事件
公共虚拟事件System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
#端区
}

我可以确认这确实是一个线程问题。我是一个在添加到集合时转储异常的白痴,因为我可能会更快地发现错误!永远不要这样做!这是不好的做法

此问题的可能解决方案如下:


我可以确认这确实是一个线程问题。我是一个在添加到集合时转储异常的白痴,因为我可能会更快地发现错误!永远不要这样做!这是不好的做法

此问题的可能解决方案如下:


问题可能出在异步填充和更新ObservableCollection的函数中。只是为了测试:尝试将集合绑定到简单的列表框,看看问题是否仍然存在。不要更改对集合的引用;清除并添加项inI get the behavior with ListBox此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection。问题可能出在异步填充和更新ObservableCollection的函数中。仅用于测试:尝试将集合绑定到查看问题是否仍然存在的简单列表框。不要更改对集合的引用;清除并添加项inI获取与ListBox相同的行为此类型的CollectionView不支持从不同于Dispatcher线程的线程对其SourceCollection进行更改。这与我现有的非常类似,只是我将属性名称的字符串硬编码,而不是使用反射。我正确地获得了ViewModel中预期的所有通知,因此我认为这在这个级别上不是问题。列表绑定到集合,所以问题似乎在ObservableCollection和list或grid之间。这与我现有的非常相似,只是我有属性名的字符串硬编码,而不是使用反射。我正确地获得了ViewModel中预期的所有通知,因此我认为这在这个级别上不是问题。列表绑定到集合,因此问题似乎位于ObservableCollection和列表或网格之间。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    class Downloads : NotifyBase
    {
        public virtual ObservableCollection<DownloadedItem> DownloadedItemCollection
        {
            get { return _DownloadedItemCollection; }
            set { _DownloadedItemCollection = value; OnPropertyChanged(System.Reflection.MethodBase.GetCurrentMethod().Name.Substring(4));  /*OnPropertyChanged("DownloadedItemCollection");*/ }
        } private ObservableCollection<DownloadedItem> _DownloadedItemCollection;

    }
}

public class NotifyBase : INotifyPropertyChanged
{
    #region NotifyBase
    // Declare the event
    public virtual event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}