2011-01-28 17 views
6

güncellememesi bir BindingList bağlı olduğu bir ListBox var. Bir üçüncü taraf uygulaması bir olayı artırdığında BindingList oluşturulur. Ben BindingList doğru bağlanmış olan görebilirsiniz ... ama hiçbir şey ListBox girer. Aynı mantığı kendi özel türlerimle kullanmıştım ve genelde çok iyi çalışıyor.BindingList bağlı ListBox

Formu sınıf

private Facade.ControlFacade _controlFacade;   
public UavControlForm() 
{ 
    InitializeComponent(); 
    _controlFacade = new UavController.Facade.ControlFacade();  
    UpdateEntityListBox(); 
} 
private void UpdateEntityListBox() 
{ 
    lsbEntities.DataSource = _controlFacade.GetEntityTally(); 
    lsbEntities.DisplayMember = "InstanceName"; 
} 

Cephe sınıf

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

Senaryo sınıf

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

Ben e görebilirsiniz Üçüncü taraf uygulamasından ateş havalandırma - bu istenilen şekilde _entityList için bir varlık ekler, ancak noothing lsbEntities eklenir - neden?

konu ve nadiren olan iyi arkadaş (veri bağlayıcı Win olduğu gibi) "gözlemci" desen

cevap

11

(bunu vb sabit görmek istiyorsanız son örneğe doğru atlama). Benim bir previous answer kullanılan ThreadedBindingList<T> kodla BindingList<T> kullanımını değiştirerek deneyebilirsiniz - ama parçacığı bu kombinasyonu ve UI Win veri bağlama kasıtlı bir kullanım söz konusu değildir.

listbox kendisi yeter ki doğru iplik oluşturacak geldikçe, liste bildirim olayları (IBindingList/IBindingListView) üzerinden bağlanma desteklemelidir. ThreadedBindingList<T>, bunu sizin için iş parçacığı ile değiştirmeye çalışır. bu bir senkronizasyon bağlamı, yani o formlarını gösteren başladıktan sonra sahip sonra UI iş parçacığı gelen ThreadedBindingList<T>, oluşturmalısınız çalışması için unutmayın.


(tek bir iplik söz konusu olduğunda) saygı listesi değiştirme bildirim yapar listbox noktayı göstermek için: ilave/ThreadedBindingList<T> diş ile hemen

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

ve (o değil Normal BindingList<T> ile çalışma:

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

Teşekkürler! Sadece bunu denemek üzereyim. Eminim neden - kodumda - farklı bir iplik kullanılıyor? Ben açıkça bir tane kullanım için tanımlamıyorum. Bana nedenini söyleyebilir misin? – wulfgarpro

+2

Sadece örnekleriniz, WinForms'daki iş parçacığının doğasını anlamama yardımcı oldu; İş parçacığı havuzu, delegeler ve olay işleme hakkında öğrendim. Zaman ve çaba için çok teşekkür ederim. Bu temel ile şimdi C# ve genel olarak yazılım geliştirme daha geniş bir anlayış kazanabilir. – wulfgarpro

+0

@WulfgarPro - Birkaç türlerinde (? BindingSource belki) başarısız bağlanma sırasında yükseltilir bir olay yoktur. Bu etkinliğe abone olursanız, aksi halde sessiz olan hata mesajları hakkında daha fazla bilgi edinebilirsiniz. –

İlgili konular