绑定列表<>ListChanged 事件 [英] BindingList<> ListChanged event

查看:34
本文介绍了绑定列表<>ListChanged 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a BindingList<> of a class set to the DataSource property of a BindingSource, which is in turn set to the DataSource property of a DataGridView.

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

1. It is my understanding that any additions to the list will fire a ListChanged event which will propagate through the BindingSource and then onto the DataGridView, which will update itself to display the change. This will happen because the events have been automatically hooked up. (Yes?)

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

This is all fine and good when all the work is done on the UI thread, but when the list is created and changed from a non-UI thread, ultimately a cross-thread exception occurs when the grid is updated. I can understand why this happens, but no how to fix it...

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

2. What I am having a tough time understanding, is where should I best intercept the ListChanged event to try and marshal things onto the UI thread? I am guessing that I need a reference to the UI thread somehow to help do this?

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

I have read many posts/articles on this, but I'm struggling because I don't fully understand the mechanisms at work here.

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

I will never be changing any items once they are in the list, only adding them, and initially clearing the list.

(我使用的是 .NET 2.0)

(I am using .NET 2.0)

推荐答案

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

You can extend BindingList to use an ISynchronizeInvoke (implemented by System.Windows.Forms.Control) to marshal the event invokations onto the UI thread.

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

Then all you need to do is use the new list type and all is sorted.

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);
    }
}

这篇关于绑定列表&lt;&gt;ListChanged 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆