加强版bindinglist_c# – BindingList不更新绑定的ListBox

本文介绍了如何处理线程和WinForms数据绑定之间的不兼容问题,提出使用ThreadedBindingList<T>类来确保UI线程正确接收列表更新。示例代码展示了如何创建和使用这个类,以及如何在ListBox中绑定数据并实现定时添加项的功能。通过这种方式,可以确保BindingList<T>在多线程环境下正确更新绑定的控件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(如果你想看到它固定等,请跳到最后一个例子)

线程和“观察者”模式(例如winforms上的数据绑定)很少是好朋友.您可以尝试替换BindingList< T>与ThreadedBindingList< T>的使用我在previous answer上使用的代码 – 但这种线程和UI的组合并不是winforms数据绑定的故意用例.

列表框本身应该支持通过列表通知事件(IBindingList / IBindingListView)进行绑定,只要它们到达形成正确的线程即可. ThreadedBindingList< T>尝试通过代表您的线程切换来解决此问题.请注意,要使其工作,您必须创建ThreadedBindingList< T>来自UI线程,在它具有同步上下文之后,即在它开始显示表单之后.

为了说明列表框确实尊重列表更改通知(处理单个线程时):

using System;

using System.ComponentModel;

using System.Windows.Forms;

class Foo

{

public int Value { get; set; }

public Foo(int value) { Value = value; }

public override string ToString() { return Value.ToString(); }

}

static class Program

{

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

using(var form = new Form())

using (var lst = new ListBox())

using (var timer = new Timer())

{

var data = new BindingList();

form.Controls.Add(lst);

lst.DataSource = data;

timer.Interval = 1000;

int i = 0;

timer.Tick += delegate

{

data.Add(new Foo(i++));

};

lst.Dock = DockStyle.Fill;

form.Shown += delegate

{

timer.Start();

};

Application.Run(form);

}

}

}

现在添加了线程/ ThreadedBindingList< T> (它不适用于常规BindingList< T>):

using System;

using System.ComponentModel;

using System.Threading;

using System.Windows.Forms;

class Foo

{

public int Value { get; set; }

public Foo(int value) { Value = value; }

public override string ToString() { return Value.ToString(); }

}

static class Program

{

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

using(var form = new Form())

using (var lst = new ListBox())

{

form.Controls.Add(lst);

lst.Dock = DockStyle.Fill;

form.Shown += delegate

{

BindingList data = new ThreadedBindingList();

lst.DataSource = data;

ThreadPool.QueueUserWorkItem(delegate

{

int i = 0;

while (true)

{

data.Add(new Foo(i++));

Thread.Sleep(1000);

}

});

};

Application.Run(form);

}

}

}

public class ThreadedBindingList : BindingList

{

private readonly SynchronizationContext ctx;

public ThreadedBindingList()

{

ctx = SynchronizationContext.Current;

}

protected override void OnAddingNew(AddingNewEventArgs e)

{

SynchronizationContext ctx = SynchronizationContext.Current;

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)

{

if (ctx == null)

{

BaseListChanged(e);

}

else

{

ctx.Send(delegate

{

BaseListChanged(e);

},null);

}

}

void BaseListChanged(ListChangedEventArgs e)

{

base.OnListChanged(e);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值