当前位置: 首页 > 编程语言 > C#

升级到.NET4.5:ItemsControl与其项目源不一致Share

时间:2023-04-11 00:36:45 C#

升级到.NET4.5:ItemsControl与其项目源不一致为了从后台线程轻松更新这些列表,我将此扩展用于ObservableCollections,它工作正常:http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx今天我安装了VS12(以及后来的.NET4.5),因为我想使用为.NET4.5编写的组件。在将我的项目升级到.NET4.5(从4.0)之前,我的数据网格在从工作线程更新时开始抛出InvalidOperationException。异常消息:抛出此异常是因为名为“(unnamed)”的控件“System.Windows.Controls.DataGridItems.Count:5”的生成器收到了与Items集合的当前状态不一致的CollectionChanged事件序列。检测到以下差异:累计计数4与实际计数5不同。[累计计数为(上次重置时的计数+#Adds-自上次重置以来的自上次重置以来)。重现代码:XAML:代码:publicpartialclassMainWindow:Window{publicExtendedObservableCollectionItems{get;私有集;}publicMainWindow(){InitializeComponent();Items=newExtendedObservableCollection();数据上下文=这个;已加载+=MainWindow_Loaded;}voidMainWindow_Loaded(objectsender,RoutedEventArgse){Task.Factory.StartNew(()=>{foreach(variteminEnumerable.Range(1,500)){Items.Add(item);}});WPF4.5提供了一些新功能来访问非UI线程上的集合。它使用WPF能够访问和修改线程上的数据集合,而不是创建集合。这允许您使用后台线程从外部源(例如数据库)接收数据,并在UI线程上显示数据。通过使用另一个线程修改集合,您的UI仍然可以响应用户交互。这可以通过使用BindingOperations类上的静态方法EnableCollectionSynchronization来完成。如果您正在收集或修改大量数据,您可能希望使用后台线程来收集和修改数据,以便用户界面保持对输入的响应。要允许多个线程访问集合,请调用EnableCollectionSynchronization方法。当您调用EnableCollectionSynchronization(IEnumerable,Object)方法的此重载时,系统会在您访问集合时锁定它。要指定您自己的用于锁定集合的回调,请调用EnableCollectionSynchronization(IEnumerable,Object,CollectionSynchronizationCallback)重载。用法如下。创建一个用作同步锁集合的对象。然后调用BindingsOperations的EnableCollectionSynchronization方法,将要同步的集合和要锁定的对象传递给它。我已经更新了您的代码并添加了详细信息。此外,我将集合更改为普通的ObservableCollection以避免冲突。publicpartialclassMainWindow:Window{publicObservableCollectionItems{get;私有集;}//锁定对象进行同步;私有静态对象_syncLock=newobject();publicMainWindow(){InitializeComponent();项目=新的ObservableCollection();//在别处启用对该集合的交叉访问BindingOperations.EnableCollectionSynchronization(Items,_syncLock);数据上下文=这个;已加载+=MainWindow_Loaded;}voidMainWindow_Loaded(objectsender,RoutedEventArgse){Task.Factory.StartNew(()=>foreach(variteminEnumerable.Range(1,500)){lock(_syncLock){Items.Add(item);}}});另请参阅:http://10/10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux总结一下这个线程,这个AsyncObservableCollection适用于.NET4和.NET4.5WPF应用程序。使用系统;使用系统集合;使用System.Collections.ObjectModel;使用System.Collections.Specialized;使用System.Linq;使用System.Windows.Data;使用System.Windows.Threading;命名空间WpfAsyncCollection{publicclassAsyncObservableCollection:ObservableCollection{publicoverrideeventNotifyCollectionChangedEventHandlerCollectionChanged;私有静态对象_syncLock=newobject();publicAsyncObservableCollection(){enableCollectionSynchronization(this,_syncLock);}protectedoverridevoidOnCollectionChanged(NotifyCollectionChangedEventArgse){使用(BlockReentrancy()){vareh=CollectionChanged;如果(eh==null)返回;vardispatcher=(fromNotifyCollectionChangedEventHandlernhineh.GetInvocationList()letdpo=nh.TargetasDispatcherObjectwheredpo!=nullselectdpo.Dispatcher).FirstOrDefault();if(dispatcher!=null&&dispatcher.CheckAccess()==false){dispatcher.Invoke(DispatcherPriority.DataBind,(Action)(()=>OnCollectionChanged(e)));}else{foreach(NotifyCollectionChangedEventHandlernhineh.GetInvocationList())nh.Invoke(this,e);}}}privatestaticvoidenableCollectionSynchronization(IEnumerablecollection,objectlockObject){varmethod=typeof(BindingOperations).GetMethod("EnableCollectionSynchronization",newType[]{typeof(IEnumerable),typeof(object)});if(method!=null){//这是.NET4.5method.Invoke(null,newobject[]{collection,lockObject});}}}}Jehof的回答是正确的我们还不能以4.5为目标,我们的自定义可观察集合已经允许后台更新(在使用Dispatcher的事件通知期间)有这个问题。如果有人觉得它有用,我在我们的应用程序中使用以下代码,它以.NET4.0为目标,以使其在执行环境为.NET4.5时使用此功能:){//等同于.NET4.5://BindingOperations.EnableCollectionSynchronization(collection,lockObject);MethodInfo方法=typeof(BindingOperations).GetMethod("EnableCollectionSynchronization",newType[]{typeof(IEnumerable),typeof(object)});if(method!=null){method.Invoke(null,newobject[]{collection,lockObject});这适用于使用VS2017版本的Windows10版本1607用户可能会遇到此问题。MicrosoftVisualStudioCommunity2017版本15.1(26403.3)发布VisualStudio.15.Release/15.1.0+26403.3Microsoft.NETFramework版本4.6.01586您不需要锁,也不需要EnableCollectionSynchronization。以上是C#学习教程:Upgradeto.NET4.5:ItemsControlanditsprojectsourcesareinconstructedandshareallthecontent.如果对你有用,需要进一步了解C#学习教程,希望大家多多关注——publicObservableCollectionfontFamilyItems;publicObservableCollectionFontFamilyItems{get{returnfontFamilyItems;}set{SetProperty(reffontFamilyItems,value,nameof(FontFamilyItems));}}公共字符串fontFamilyItem;publicstringFontFamilyItem{get{返回fontFamilyItem;));}}privateListGetItems(){列表字体=newList();foreach(Fonts.SystemFontFamilies中的System.Windows.Media.FontFamily字体){fonts.Add(font.Source);....其他东西..}返回字体;}publicasyncvoidOnFontFamilyViewLoaded(objectsender,EventArgse){DisposableFontFamilyViewLoaded.Dispose();任务>getItemsTask=Task.Factory.StartNew(GetItems);try{foreach(awaitgetFamilygetItemsTask中的字符串项目).Add(item);}}catch(Exceptionx){thrownewException("Error-"+x.消息);}...otherstuff}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: