如何正确地从后端线程更新数据绑定的datagridview [英] How do you correctly update a databound datagridview from a background thread

查看:164
本文介绍了如何正确地从后端线程更新数据绑定的datagridview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义对象实现INotifyPropertyChanged。我收集了这些对象,其中集合基于BindingList
我已经为集合创建了绑定源,并设置了bindingsource和datagridview的数据源。



除了我需要从后台线程更新自定义对象的属性外,一切都很好用。当我这样做,我得到以下错误:


BindingSource不能是自己的数据源。不要将DataSource和DataMember属性设置为返回BindingSource的值


我发现以下帖子似乎有我的确切问题(和解决方案?),但我不能弄清楚。


http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/线程/ 3566f7c7-eb47-422e-ab09-9549a18da360 /


我创建并初始化了每个帖子中的操作变量我的业务对象,然后我将两个事件函数放入我的收集类。这个编译正确,但在运行时无一例外。



我看到很多帖子说使用Invoke / Begin Invoke,但是我没有在UI上调用任何函数,只是更新业务对象,所以我不知道我会在哪里调用调用。一个限制:我希望业务对象不知道谁正在显示它(因为有多个消费者),所以将GUI引用发送到业务对象,以便我以后可以使用这些引用调用invoke不是一个选项。

解决方案

我在一个论坛上发现这个类。只需使用这个而不是BindingList

  using System; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;

使用System.ComponentModel;
使用System.Threading;

命名空间实用程序
{
public class ThreadedBindingList< T> :BindingList< T>
{
SynchronizationContext ctx = SynchronizationContext.Current;

protected override void OnAddingNew(AddingNewEventArgs e)
{

if(ctx == null)
{
BaseAddingNew(e);
}
else
{
ctx.Send(委托
{
BaseAddingNew(e);
},null);
}
}
void BaseAddingNew(AddingNewEventArgs e)
{
base.OnAddingNew(e);
}
protected override void OnListChanged(ListChangedEventArgs e)
{
// SynchronizationContext ctx = SynchronizationContext.Current;
if(ctx == null)
{
BaseListChanged(e);
}
else
{
ctx.Send(委托
{
BaseListChanged(e);
},null);
}
}
void BaseListChanged(ListChangedEventArgs e)
{
base.OnListChanged(e);
}
}
}


I have a custom object that implements INotifyPropertyChanged. I have a collection of these objects where the collection is based on BindingList I have created a binding source for the collection, and set the datasources of the bindingsource and datagridview.

Everything works great, except I need to update properties on the custom object from background threads. when I do so, I get the following error :

BindingSource cannot be its own data source. Do not set the DataSource and DataMember properties to values that refere back to BindingSource

I found the following post that seems to have my exact problem (and solution?) but I cannot quite figure it out.

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/3566f7c7-eb47-422e-ab09-9549a18da360/

I created and initialized the oper variables per the post in my business object, and then I put the two event functions into my collection class. This compiled correctly, but hangs without exception when run.

I have seen many posts saying to use Invoke/Begin Invoke, but I am not calling any functions on the UI, just updating business objects, so I am not sure where I would put the invoke calls.

One restriction : I want the business object to remain unaware of who is displaying it (as there are multiple consumers) so sending in GUI references into the business object so that I am later able to call invoke using those references is not an option.

解决方案

I found this class in a forum that works. Just use this instead of BindingList

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;
using System.Threading;

namespace Utility
{
    public class ThreadedBindingList<T> : BindingList<T>
    {
        SynchronizationContext ctx = SynchronizationContext.Current;

        protected override void OnAddingNew(AddingNewEventArgs e)
        {

            if (ctx == null)
            {
                BaseAddingNew(e);
            }
            else
            {
                ctx.Send(delegate
                {
                    BaseAddingNew(e);
                }, null);
            }
        }
        void BaseAddingNew(AddingNewEventArgs e)
        {
            base.OnAddingNew(e);
        }
        protected override void OnListChanged(ListChangedEventArgs e)
        {
           // SynchronizationContext ctx = SynchronizationContext.Current;
            if (ctx == null)
            {
                BaseListChanged(e);
            }
            else
            {
                ctx.Send(delegate
                {
                    BaseListChanged(e);
                }, null);
            }
        }
        void BaseListChanged(ListChangedEventArgs e)
        {
            base.OnListChanged(e);
        }
    } 
}

这篇关于如何正确地从后端线程更新数据绑定的datagridview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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