gpt4 book ai didi

c# - BindingList<> ListChanged 事件

转载 作者:IT王子 更新时间:2023-10-29 04:42:55 33 4
gpt4 key购买 nike

我有一个类的 BindingList<> 设置为 BindingSource 的 DataSource 属性,而 BindingSource 又设置为 DataGridView 的 DataSource 属性。

1.据我了解,列表中的任何添加都会触发一个 ListChanged 事件,该事件将通过 BindingSource 传播,然后传播到 DataGridView,DataGridView 将自行更新以显示更改。这会发生,因为事件已经自动连接。 (是吗?)

当所有工作都在 UI 线程上完成时,这一切都很好,但是当从非 UI 线程创建和更改列表时,最终会在更新网格时发生跨线程异常。我能理解为什么会发生这种情况,但不知道如何解决...

2。我很难理解的是,我应该在哪里最好地拦截 ListChanged 事件以尝试将事情编码到 UI 线程上?我猜想我需要以某种方式引用 UI 线程来帮助执行此操作?

我已经阅读了很多关于此的帖子/文章,但我正在苦苦挣扎,因为我不完全理解这里的工作机制。

一旦项目在列表中,我将永远不会更改任何项目,只会添加它们,并最初清除列表。

(我正在使用 .NET 2.0)

最佳答案

您可以扩展 BindingList 以使用 ISynchronizeInvoke(由 System.Windows.Forms.Control 实现)将事件调用编码到 UI 线程。

然后您需要做的就是使用新的列表类型,所有内容都已排序。

public partial class Form1 : System.Windows.Forms.Form {

SyncList<object> _List;
public Form1() {
InitializeComponent();
_List = new SyncList<object>(this);
}
}

public class SyncList<T> : System.ComponentModel.BindingList<T> {

private System.ComponentModel.ISynchronizeInvoke _SyncObject;
private System.Action<System.ComponentModel.ListChangedEventArgs> _FireEventAction;

public SyncList() : this(null) {
}

public SyncList(System.ComponentModel.ISynchronizeInvoke syncObject) {

_SyncObject = syncObject;
_FireEventAction = FireEvent;
}

protected override void OnListChanged(System.ComponentModel.ListChangedEventArgs args) {
if(_SyncObject == null) {
FireEvent(args);
}
else {
_SyncObject.Invoke(_FireEventAction, new object[] {args});
}
}

private void FireEvent(System.ComponentModel.ListChangedEventArgs args) {
base.OnListChanged(args);
}
}

关于c# - BindingList<> ListChanged 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1351138/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com