2010-01-11 15 views
10

छोड़ते हैं, मैंने Databound Windows Forms control does not recognize change until losing focus में उत्तर देखा।सी # डाटाबेस विंडोज फॉर्म नियंत्रण तब तक मूल्य बनाए रखता है जब तक आप फ़ील्ड

लेकिन यह मेरे लिए सवाल का पूरी तरह उत्तर नहीं देता है। मेरे पास एक ही स्थिति है। ToolStrip_click पर, मैं अपने सभी नियंत्रणों से गुजरता हूं और मैं "WriteValue()" को मजबूर करता हूं, लेकिन यह अभी भी सहेजने से पहले पिछले मान पर वापस आता है। क्या कोई सुझाव दे सकता है कि मैं इसे कैसे ठीक कर सकता हूं? क्या मैंने इसे गलत तरीके से कार्यान्वित किया?

(वर्तमान (गैर काम कर रहे) समाधान के लिए कोड देखें।)

private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
{ 
    // Make sure that all items have updated databindings. 
    foreach (Control C in this.Controls) 
    { 
     foreach (Binding b in C.DataBindings) 
     { 
      // Help: this doesn't seem to be working. 
      b.WriteValue(); 
     } 
    } 
} 

कोड अब बहुत सरल है, लेकिन यह एक काफी हैक है। मुझे यह जानकर बहुत खुशी होगी कि इसके लिए एक और "उचित" फिक्स है या नहीं।

private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
{ 
    // Make sure that all text fields have updated by forcing everything 
    // to lose focus except this lonely little label. 
    label44.Focus(); 
} 

उत्तर

24

समस्या यह है कि आपके डेटाबेस नियंत्रण सत्यापन पर अद्यतन करने के लिए सेट हैं।

आपको डेटासॉर्सअपडेटमैड.ऑनप्रॉपर्टी चेंज किए गए प्रत्येक डाटाबेस नियंत्रण के डेटासोर्सअपडेट मोड को सेट करने की आवश्यकता है। उदाहरण के लिए, एक डेटाबाउंड पाठ बॉक्स:

this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", 
    this.someBindingSource, "SomeProperty", true, 
    System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 

तुम भी द्वारा डिजाइनर में डेटा स्रोत अद्यतन मोड सेट कर सकते हैं:

नियंत्रण का चयन और संपत्ति विंडो के लिए जा रहा -> (databindings) -> (उन्नत)

-> ड्रॉपडाउन सूची में [डेटा स्रोत अपडेट मोड] को ऑनप्रॉपर्टी चेंज में सेट करें।

चीयर्स

+0

यह बिल्कुल सही था ... आप नहीं जानते कि यह समस्या मुझे कितनी देर तक पागल कर रही है। धन्यवाद। यह बहुत आसान लगता है, इसे वापस देखकर, लेकिन सभी "विशेषज्ञ", यहां तक ​​कि माइक्रोसॉफ्ट से भी, मैंने यह भी पूछा है कि इससे भी डूब गया था। अच्छा जॉब! – Jerry

+1

_ "प्रॉपर्टी विंडो -> (डेटा बाइंडिंग्स) -> (एडवांस्ड) ... ... ड्रॉपप्रॉपलिस्ट में ऑनप्रॉपर्टी चेंज में सेट करें ... "_ - ओएमजी मैं कभी नहीं जानता था कि वहां था! मेरी इच्छा है कि मैं आपको एक अरब बार अच्छा सर दे सकता हूं!: डी – MickyD

3

एक टूलस्ट्रिप बटन क्लिक करते समय फोकस नहीं लेता है। आप कुछ कोड जोड़ सकते हैं (अस्थायी रूप से) एक और नियंत्रण पर ध्यान केंद्रित करें। आप एक लेबल पर ध्यान केंद्रित कर सकते हैं (एक तटस्थ डमी के रूप में)।

+0

ठीक है ... आश्चर्यजनक रूप से, यह काम किया ... मैं खुशी से आपको इसके लिए "अप" दूंगा। लेकिन मुझे लगता है कि लेबल फोकस देना एक हैक का थोड़ा सा है। मुझे इसे "सर्वोच्च उत्तर" के रूप में चिह्नित करने में संकोच नहीं है जब तक कि किसी और के पास उज्ज्वल विचार न हो। क्या यह वही काम करने का एक "उचित" तरीका है? – Jerry

+0

उदाहरण के लिए, यदि उपयोगकर्ता अपने ऐप को सहेजने के लिए "Alt-S" का उपयोग करता है तो क्या होगा? आधिकारिक तौर पर कभी भी क्लिक नहीं किया गया था। – Jerry

+0

Alt + S: एक ही समस्या। –

0

इस प्रयास करें:

private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
{ 
    // Make sure that all items have updated databindings. 
    foreach (Control C in this.Controls) 
    { 
     C.SuspendLayout(); 
     foreach (Binding b in C.DataBindings) 
     { 
      // Help: this doesn't seem to be working. 
      b.WriteValue(); 
     } 
     C.ResumeLayout(); 
    } 
} 
+0

नहीं। = (फ़ोकस किए गए फ़ील्ड अभी भी उनके पिछले मान हैं। – Jerry

3

क्या आप के लिए बाध्य कर रहे हैं? गंदी स्थिति और बचत और जब भी गंदी स्थिति को संभालने के लिए

private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
{ 
    // Assuming that you are binding to bindingSource1: 
    bindingSource1.EndEdit(); 
} 

मैं अपने रूपों पर एक ISave इंटरफ़ेस को लागू: यदि यह एक डेटासेट, DataTable, आदि, या बेहतर अभी तक, एक BindingSource है, तो आप EndEdit बुलाना चाहिए चेक किया गया है (जब भी IsDirty कहा जाता है), मैं हमेशा अपने बंधन स्रोत पर EndEdit:

interface ISave 
{ 
    bool IsDirty; 
    bool Save(bool force); 
} 
इस इंटरफेस के साथ

, कब, कहते हैं, आवेदन बंद हो रहा है, मैं आसानी से अपने खुले MdiChild खिड़कियों को देखने के लिए जाँच के माध्यम से पुनरावृति कर सकते हैं अगर कोई जानकारी बच्चे के फार्म को 012 पर कास्ट करके सहेजी गई हैऔर IsDirty के मूल्य की जांच। यहां, मैं एंडीडिट को उचित बाध्यकारी स्रोत पर या यदि लागू हो, तो बाध्यकारी नियंत्रण (उदाहरण के लिए, एक ग्रिड) पर कॉल करें।

और रैंपल को क्षमा करें, लेकिन मैंने सोचा कि यह सहायक हो सकता है। शेष इस प्रकार काम करते हैं:

Save() "बल" का पैरामीटर लेता है, इसलिए मेरे पास "फॉर्म & बंद करें" बटन एक फॉर्म हो सकता है (उपयोगकर्ता को अतिरिक्त क्लिक या पुष्टिकरण बचाता है कि क्या वे अपने परिवर्तनों को सहेजना चाहते हैं) । अगर बल गलत है, तो Save() विधि उपयोगकर्ता से पूछने के लिए ज़िम्मेदार है अगर वे सहेजना चाहते हैं। यदि यह सच है, तो यह माना जाता है कि उपयोगकर्ता ने पहले से ही फैसला कर लिया है कि वे निश्चित रूप से अपनी जानकारी को सहेजना चाहते हैं, और यह पुष्टि छोड़ दी गई है।

Save() कॉलिंग कोड निष्पादित करना जारी रखना सुरक्षित है (संभवतः एक फॉर्म_Closing ईवेंट)। इस मामले में, (यदि बल गलत था), एक YesNoCancel MessageBox दिया गया, उपयोगकर्ता या तो हां या कोई और सहेजने से कोई त्रुटि नहीं आई। या, Save() उपयोगकर्ता ने को को रद्द करने की स्थिति में झूठी वापसी की है या कोई त्रुटि हुई है (दूसरे शब्दों में, कॉलिंग कोड को फ़ॉर्म को रद्द करने के लिए कह रहा है)।

आप त्रुटियों को कैसे हैंडल अपने अपवाद को पकड़ने सम्मेलनों पर निर्भर करता है - यह या तो Save() विधि में पकड़ा जा सकता है और उपयोगकर्ता के लिए या शायद इस तरह के FormClosing के रूप में एक घटना जहां e.Cancel तो सही पर सेट किया जाएगा में दिखाया गया है। ,

private void btnSaveAndClose_Click(object sender, EventArgs e) 
{ 
    if (IsDirty) 
     if (Save(true)) 
      Close(); 
} 

वैसे भी:

एक रूप समापन समारोह के साथ प्रयोग किया जाता है यह इस तरह दिखेगा:

private void form1_FormClosing(object sender, CancelEventArgs e) 
{ 
    if (IsDirty) 
     e.Cancel = !Save(false); 
} 

एक एक & सहेजें बंद करें बटन से बचाने के लिए मजबूर के साथ प्रयोग किया जाता है, यह इस प्रकार दिखाई देगा आपसे पूछा गया उससे थोड़ा अधिक, लेकिन मुझे उम्मीद है कि यह मदद करता है!

0

इसने मुझे अतीत में फेंक दिया है। DataSourceUpdateMode को ऑनप्रॉपर्टी पर सेट किया जा रहा है, डेटा स्रोत में अंतर्निहित कॉलम केवल पढ़ने के लिए नहीं होना चाहिए।

एक DataTable में अपने स्तंभ के लिए यह जाँच करें:

Public Function MakeReadOnlyFalse(ByVal dt As DataTable) As DataTable 

    For Each col As DataColumn In dt.Columns 
     If col.ReadOnly Then 
      col.ReadOnly = False 
     End If 
    Next 

    Return dt 
End Function 
:

dataTable.Columns("ColumnName").ReadOnly

मैं भी एक समारोह है कि सभी स्तंभों सेट ReadOnly नहीं होने के लिए है, जो काम एक बार से अधिक में आ गया है बनाया

-1

मेरे लिए यह सबसे खराब है। अगर मैं अद्यतन स्रोत मोड को ऑनप्रॉपर्टी पर संयोजित करता हूं, तो यह व्यवहार करता है जैसे कि मैंने इसे ऑनवॉलिशन मोड में सेट किया था! Wpf में बाइंडिंग कहीं अधिक बेहतर हैं।

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

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