2009-04-20 13 views
5

नीचे दी गई छवि से पता चलता है कि मेरा कोड कैसे काम करता है। जब मैं बटन 2 दबाता हूं तो सूची बॉक्स अपडेट होता है, लेकिन जब मैं बटन 1 दबाता हूं। क्यूं कर?बाध्य डेटा बदलते समय Winforms listbox अद्यतन नहीं हो रहा है

pseudo code http://i44.tinypic.com/mj69oj.gif

संबंधित सूत्रण समस्या है? यदि ऐसा है, तो मुझे कॉल (शुरुआत) को कॉल कहां जोड़ना चाहिए?

ध्यान देने योग्य एक दिलचस्प बात यह है कि यदि मैं पहले बटन 1 दबाता हूं और फिर बटन 2 बटन 1 द्वारा उत्पन्न डेटा दिखाता है तो मैं बटन 2 पर क्लिक करता हूं। तो ऐसा लगता है जैसे DoFoo द्वारा उत्पन्न डेटा कहीं भी buffered है, और फिर बटन 2 दबाए जाने के बाद सूची बॉक्स में धक्का दिया।

संपादित करें:

मैं प्रपत्र कोड को AddNumber जोड़ने की कोशिश की, और आह्वान करने के लिए जब listBox1.InvokeRequired सच रिटर्न एक फोन गयी। यह समस्या हल करता है, लेकिन डिजाइनों में सबसे अच्छा नहीं है। मैं नहीं चाहता कि जीयूआई को मॉडल के हिस्से की सूची में आइटम जोड़ने के तरीके के बारे में "चिंता" करना पड़े।

सूची सूची में आंतरिक सूची में जोड़ने के पीछे तर्क को कैसे रखा जा सकता है, जबकि सूची बदलते समय भी गुई को अपडेट किया जा रहा है?

संपादित करें 2:

अब हम पुष्टि की है कि है कि यह एक सूत्रण मुद्दा मैं छवि को नवीनीकृत किया है और अधिक बारीकी से वास्तविक कोड मैं पर काम कर रहा हूँ के डिजाइन को प्रतिबिंबित है।

जबकि लुसेरो का सुझाव अभी भी समस्या हल करता है, मैं उस चीज़ की उम्मीद कर रहा था जिसके लिए फॉर्म को डीएल या सीडीएलप्रैपर के बारे में कुछ भी जानने की आवश्यकता नहीं है।

मॉडल (ListBoxDataBindingSource आदि) बिल्कुल दृश्य के बारे में (listboxes, बटन, लेबल आदि) कुछ भी नहीं पता होना चाहिए

उत्तर

2

मेरा अनुमान है कि इस अद्यतन संदेश गलत थ्रेड में प्रबंधित किया जा रहा की वजह से है। पृष्ठभूमि: प्रत्येक धागे का अपना संदेश कतार होता है। संदेश कतार में पोस्ट किए गए संदेश डिफ़ॉल्ट रूप से कॉलर के समान थ्रेड में उतरेंगे। इसलिए, कॉलबैक शायद गलत धागे पर एक संदेश पोस्ट करेगा।

इसे आज़माएं: AddNumber() विधि को फॉर्म में ले जाएं और सही थ्रेड में आइटम जोड़ने के लिए Invoke() (नियंत्रण द्वारा विरासत) का उपयोग करें। यह इस मुद्दे से छुटकारा पा सकता है।

अपने अनुवर्ती प्रतिबिंबित करने के लिए संपादित करें: UI को आपके घटक के बारे में पता नहीं होना चाहिए। आपको अपनी सूची और यूआई में आइटम जोड़ने के बीच बस एक उचित सिंक्रनाइज़ेशन है, क्योंकि थ्रेड मैचों में यूआई अपडेट काम करेंगे। इसलिए, हो सकता है कि आप अपनी कक्षा में नियंत्रण की आपूर्ति करना चाहें जो बाइंडिंगलिस्ट को लपेटता है, और उसके बाद सूची में ही आमंत्रण करता है। यह सूची यूआई थ्रेड पर अपरिवर्तित करने के बारे में चिंता करता है और सही यूआर पर हैंडलर को आक्रमण करने के बाहरी यूआई और बाहरी घटक दोनों से चिंता करता है।

इस तरह:

internal class ListBoxDataBindingSource { 
    private readonly Control uiInvokeControl; 
    private readonly BindingList<Item> list = new BindingList<Item>(); 

    public ListBoxDataBindingSource(Control uiInvokeControl) { 
     if (uiInvokeControl == null) { 
      throw new ArgumentNullException("uiInvokeControl"); 
     } 
     this.uiInvokeControl = uiInvokeControl; 
     CDIIWrapper.setFP(AddNumber); 
    } 

    public void AddNumber(int num) { 
     Item item = new Item(num.ToString()); 
     if (uiInvokeControl.InvokeRequired) { 
      uiInvokeControl.Invoke(list.Add, item); 
     } else { 
      list.Add(item); 
     } 
    } 

    private BindingList<Item> List { 
     get { 
      return list; 
     } 
    } 
} 
+0

मैं समझता हूं कि समस्या क्या है, अब हमें सिर्फ एक अच्छे समाधान के साथ आना है :) मैं इसे एमवीसी पैटर्न के अनुसार डिजाइन करने की कोशिश कर रहा हूं, इसलिए ListBoxDa को दे रहा हूं taBindingSource (मॉडल का हिस्सा) एक नियंत्रण (दृश्य का हिस्सा) के बारे में पता है आमतौर पर खराब अभ्यास के रूप में देखा जाता है। – Tobbe

+0

ठीक है, यह वास्तव में नियंत्रण के बारे में नहीं जानता है, लेकिन केवल सही धागे को जोड़ने के लिए हॉट कॉल मार्शल को गर्म करने की आवश्यकता है। आप अपनी खुद की मार्शलिंग क्लास बना सकते हैं जो नियंत्रण के बारे में जानता है और सूची में पास हो जाता है, ताकि यह पहलू ठीक से छिपा हुआ हो। – Lucero

+0

(* @ टोबे: * शायद [यह उत्तर] (http://stackoverflow.com/questions/3381536/winforms-data-binding-to-business-objects-in-a-multi-threaded-scenario-without-in/3381685 # 3381685) मेरे पिछले प्रश्नों में से एक के लिए - [Winforms बिना किसी प्रसंस्करण के बहु-थ्रेडेड परिदृश्य में व्यावसायिक वस्तुओं के लिए बाध्यकारी?] (Http://stackoverflow.com/q/3381536/240733) - लागू होगा यहां।) – stakx

0
इसके बजाय setFP होने के

lbDataBindingSource.AddNumber को कॉलबैक निर्धारित करते हैं, अपने कोड कॉलबैक संभाल करने में एक निजी विधि बनाने और उसके बाद कि कॉलबैक से lbDataBindingSource.AddNumber कहते हैं।

void MyForm_Load(object sender, EventArgs e) 
{ 
    //... 

    cdll.setFP(FPCallback); 
} 

private void FPCallback(int num) 
{ 
    lbDataBindingSoruce.AddNumber(num); 
} 
1

मुझे पता है कि यह पुराना है, हालांकि मुझे एक जैसी ही समस्या थी।

यहां समाधान था: BindingList not updating bound ListBox

+0

धन्यवाद। मैंने इस परियोजना को बहुत समय पहले बर्फ पर रखा था, लेकिन जब मैं इसे फिर से उठाता हूं तो मैं देखता हूं कि इससे मदद मिलती है :) – Tobbe

0

मैं bindinglist के लिए चीजों को जोड़ने के लिए मेरे विचार मॉडल कॉल करने के लिए की जरूरत है, तो मैं एक गुमनाम समारोह

Lucero के जवाब देने के लिए संदर्भ और निम्नलिखित पोस्ट लिखने के लिए की जरूरत है: Anonymous method in Invoke call

मेरे कोड:

listBox.Invoke((Action)delegate 
{ 
    MyViewModel.AddItem(param1, param2); 
}); 
संबंधित मुद्दे