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

BindingListListChanged事件分享

时间:2023-04-10 18:19:09 C#

BindingListListChanged事件我有一个类BindingList设置为BindingSource的DataSource属性,设置为DataGridView的DataSource属性。1.我的理解是,对列表的任何添加都会触发一个ListChanged事件,该事件将通过BindingSource传播,然后传播到DataGridView,后者将自行更新以显示更改。这将发生,因为事件是自动连接的。(是吗?)当所有工作都在UI线程上完成时,这一切都很好,但是当从非UI线程创建和更改列表时,您最终会在更新网格时出现跨线程异常。我能理解为什么会这样,但没有办法解决它......2.我很难理解,我应该在哪里最好地拦截ListChanged事件以尝试将事情编组到UI线程中?我猜我需要对UI线程的引用以某种方式帮助解决这个问题?我已经阅读了很多关于此的帖子/文章,但我正在苦苦挣扎,因为我不完全了解这里的工作机制。一旦它们在列表中,我从不更改任何项目,只是添加它们,并最初清除列表。(我使用的是.NET2.0)您可以扩展BindingList以使用ISynchronizeInvoke(由System.Windows.Forms.Control实现)将事件调用编组到UI线程。然后您需要做的就是使用新的列表类型,并对所有列表进行排序。publicpartialclassForm1:System.Windows.Forms.Form{SyncList_List;publicForm1(){InitializeComponent();_List=newSyncList(这个);}}公共类SyncList:System.ComponentModel.BindingList{privateSystem.ComponentModel。ISynchronizeInvoke_SyncObject;私有System.Action_FireEventAction;publicSyncList():this(null){}publicSyncList(System.ComponentModel.ISynchronizeInvokesyncObject){_SyncObject=syncObject;_FireEventAction=FireEvent;}protectedoverridevoidOnListChanged(System.ComponentModel.ListChangedEventArgsargs){if(_SyncObject==null){FireEvent(args);}else{_SyncObject.Invoke(_FireEventAction,newobject[]{args});}}privatevoidFireEvent(System.ComponentModel.ListChangedEventArgsargs){基础。OnListChanged(参数);这一点很公平。在幕后,其他对象(如CurrencyManager和Binding)确保在基础数据源更改时更新控件。将项目添加到数据绑定的BindingList会触发一系列事件,这些事件最终会尝试更新DataGridView。由于只能从UI线程更新UI,因此您应该通过Control.Invoke从UI线程将项目添加到BindingList。我整理了一个快速示例,该示例创建了一个带有DataGridView、BindingSource和Button的表单。该按钮旋转另一个线程,该线程模拟获取包含在BindingList中的新项目。包含本身是通过Control.Invoke在UI线程中完成的。以上就是C#学习教程:BindingListListChanged事件分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多加关注——publicpartialclassBindingListChangedForm:Form{BindingListpeople=newBindingList();动作personAdder;publicBindingListChangedForm(){InitializeComponent();this.dataGridView1.AutoGenerateColumns=true;this.bindingSource1.DataSource=this.people;this.personAdder=this.PersonAdder;}privatevoidbutton1_Click(objectsender,EventArgse){Threadt=newThread(this.GotANewPersononBackgroundThread);t.开始();}//在后台线程上运行。privatevoidGotANewPersononBackgroundThread(){Personperson=newPerson{Id=1,Name="Foo"};//调用UI线程上的委托。this.Invoke(this.personAdder,person);}//在UI线程上调用。voidPersonAdder(Personperson){this.people.Add(person);}}publicclassPerson{publicintId{get;放;}公共字符串名称{得到;放;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: