c# – BindingList不更新绑定的ListBox

c# – BindingList不更新绑定的ListBox,第1张

概述我有一个绑定到BindingList的ListBox. BindingList是在第三方应用程序引发事件时构建的.我可以看到绑定列表正确绑定…但没有任何内容进入ListBox.我使用了与我自己的一些自定义类型完全相同的逻辑,它通常工作得很好. 表格类 private Facade.ControlFacade _controlFacade; public UavControlForm 我有一个绑定到BindingList的ListBox. BindingList是在第三方应用程序引发事件时构建的.我可以看到绑定列表正确绑定…但没有任何内容进入ListBox.我使用了与我自己的一些自定义类型完全相同的逻辑,它通常工作得很好.

表格类

private Facade.ControlFacade _controlFacade;        public UavControlForm(){    InitializeComponent();      _controlFacade = new UavController.Facade.ControlFacade();          UpdateEntityListBox();}private voID UpdateEntityListBox(){    lsbEntitIEs.DataSource = _controlFacade.GetEntityTally();    lsbEntitIEs.displayMember = "Instancename";}

门面课

private Scenario _scenario;public ControlFacade(){    _scenario = new Scenario();}public BindingList<AgStkObject> GetEntityTally(){    BindingList<AgStkObject> entityTally = _scenario.EntityTally;    return entityTally;}

场景类

private static BindingList<IAgStkObject> _entityTally = new BindingList<AgStkObject>();public Scenario(){    if (UtilStk.CheckThatStkIsAvailable())    {        UtilStk.StkRoot.OnStkObjectAdded += new IAgStkObjectRootEvents_OnStkObjectAddedEventHandler(TallyScenarioObjects);        UtilStk.StkRoot.OnStkObjectDeleted += new IAgStkObjectRootEvents_OnStkObjectDeletedEventHandler(TallyScenarioObjects);    }          }private voID TallyScenarioObjects(object sender){    List<AgStkObject> tallyOfStkObjects = UtilStk.GetRunningTallyOfAllStkObjects();    List<string> stkObjectnames = UtilStk.GetInstancenamesOfStkObjects(tallyOfStkObjects);    foreach (string stkObjectname in stkObjectnames)    {        if (!SearchFlightUavTallyByname(stkObjectname))        {            if (!SearchLoiterUavTallyByname(stkObjectname))            {                if (!SearchEntityTallyByname(stkObjectname))                {                    int i = stkObjectnames.IndexOf(stkObjectname);                    _entityTally.Add(tallyOfStkObjects[i]);                }            }        }    }}

我可以看到来自第三方应用程序的事件触发 – 这会根据需要向_entityList添加一个实体,但是没有任何内容添加到lsbEntitIEs – 为什么?

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

线程和“观察者”模式(例如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<Foo>();            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<Foo> data = new ThreadedBindingList<Foo>();                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<T> : BindingList<T>{    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);    }}
总结

以上是内存溢出为你收集整理的c# – BindingList不更新绑定的ListBox全部内容,希望文章能够帮你解决c# – BindingList不更新绑定的ListBox所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1263590.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存