2011-01-28 13 views
6

अपडेट नहीं कर रहा है मेरे पास ListBox है जो BindingList से जुड़ा हुआ है। BindingList तब बनाया गया है जब कोई तृतीय पक्ष एप्लिकेशन किसी ईवेंट को उठाता है। मैं 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 में कुछ भी नहीं जोड़ा गया है - क्यों?

उत्तर

11

(पिछले उदाहरण के लिए सही कूद अगर आप इसे आदि तय देखना चाहते हैं)

धागे और शायद ही कभी रहे हैं अच्छे दोस्त (जैसे डेटा-बाइंडिंग WinForms को) "पर्यवेक्षक" पैटर्न। previous answer पर उपयोग किए गए ThreadedBindingList<T> कोड के साथ आप अपने BindingList<T> उपयोग को प्रतिस्थापित करने का प्रयास कर सकते हैं - लेकिन थ्रेड और यूआई का यह संयोजन Winforms डेटा-बाइंडिंग का जानबूझकर उपयोग-मामला नहीं है।

लिस्टबॉक्स ही जब तक आएंगे, उन्हें सही धागा फार्म सूची अधिसूचना घटनाओं (IBindingList/IBindingListView) के माध्यम से बाध्यकारी का समर्थन करना चाहिए। ThreadedBindingList<T> आपकी ओर से थ्रेड-स्विचिंग द्वारा इसे ठीक करने का प्रयास करता है। ध्यान दें कि इसके लिए आपको को के बाद बनाने के बाद बनाने के बाद यह एक सिंक-संदर्भ है, यानी इसके बाद फॉर्म प्रदर्शित करना शुरू हो गया है।


मुद्दा यह है कि लिस्टबॉक्स सम्मान सूची परिवर्तन सूचनाएं करता है (जब एक ही धागे के साथ काम कर) इसे समझने के लिए:

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

धन्यवाद! मैं बस इसे आजमाने की कोशिश कर रहा हूँ। मुझे यकीन नहीं है कि क्यों - मेरे कोड में - एक अलग धागा का उपयोग किया जा रहा है? मैं स्पष्ट रूप से उपयोग के लिए परिभाषित नहीं करता हूं। क्या आप मुझे बता सकते हैं क्यों? – wulfgarpro

+2

न केवल आपके उदाहरणों ने मुझे WinForms में धागे की प्रकृति को समझने में मदद की है; मैंने थ्रेड पूलिंग, प्रतिनिधि और इवेंट हैंडलिंग के बारे में सीखा है। आपके समय और प्रयास के लिए बहुत बहुत धन्यवाद। इस आधार पर अब मैं सामान्य रूप से सी # और सॉफ्टवेयर विकास की व्यापक समझ प्राप्त कर सकता हूं। – wulfgarpro

+0

@WulfgarPro - कुछ प्रकारों पर (बाध्यकारी स्रोत शायद?) एक ऐसी घटना है जो बाध्यकारी विफल होने पर उठाई जाती है। यदि आप इस घटना की सदस्यता लेते हैं तो आप त्रुटि संदेशों के बारे में बहुत अधिक जानकारी प्राप्त कर सकते हैं जो अन्यथा चुप हैं। –

संबंधित मुद्दे