2010-01-04 16 views
11

मान लीजिए कि हम एक विंडोज़ अनुप्रयोग में निम्न कोड करते हैं:ComboBox.SelectedValue Windows में पाठ जब DropDownStyle = DropDownList दिखाया गया है से मेल नहीं खाती 7

ComboBox comboBox = new ComboBox() 
{ 
    AutoCompleteMode = AutoCompleteMode.SuggestAppend, 
    AutoCompleteSource = AutoCompleteSource.ListItems, 
    DataSource = new string[] { "", "Ark", "Boat", "Bucket" }, 
    DropDownStyle = ComboBoxStyle.DropDownList 
}; 
this.Controls.Add(comboBox); 

TextBox textBox = new TextBox() 
{ 
    Left = comboBox.Right, 
    Top = comboBox.Top, 
    ReadOnly = true 
}; 
textBox.DataBindings.Add("Text", comboBox, "SelectedValue"); 
this.Controls.Add(textBox); 

यहाँ कोई जादू है, बस एक ComboBox स्ट्रिंग की एक सूची के लिए बाध्य । TextBoxComboBox के SelectedValue प्रदर्शित करता है।

जब मैं ComboBox और टैब दूर में "बाल्टी" टाइप करता हूं तो मुझे अप्रत्याशित व्यवहार मिल रहा है। किसी कारण से ComboBox "नाव" प्रदर्शित करता है लेकिन TextBox "बाल्टी" प्रदर्शित करता है। मैं उन दोनों को "बाल्टी" प्रदर्शित करने की उम्मीद करता हूं।

अगर मैं DropDownStyle को DropDown में बदलता हूं तो यह अपेक्षा करता है, लेकिन मैं नहीं चाहता कि उपयोगकर्ता अपनी इच्छानुसार कुछ भी टाइप कर सकें। उन्हें केवल सूची में मौजूद वस्तुओं को टाइप करने में सक्षम होना चाहिए।

और भी दिलचस्प बात यह है कि, "बाल्टी" टाइप करने और दूर टैब्स करने के बाद, यदि मैं फिर से "बाल्टी" टाइप करता हूं तो यह दोनों में "बाल्टी" प्रदर्शित करेगा। यदि मैं तीसरा प्रयास करता हूं, तो यह ComboBox और 'टेक्स्टबॉक्स' के लिए "बाल्टी" के लिए "नाव" पर वापस जाता है। तो ऐसा लगता है कि यह सभी बी के माध्यम से साइकिल चल रहा है।

मैंने इसे तब तक नहीं देखा जब तक कि मैंने हाल ही में एक्सपी से विंडोज 7 तक अपग्रेड नहीं किया। मैं नहीं देखता कि इसके साथ क्या करने के लिए कुछ भी हो सकता है, लेकिन मैं इसे किसी भी तरह से फेंक रहा हूं।

यदि यह व्यवहार सही है, तो क्या कोई मुझे बता सकता है कि मुझे अपने अपेक्षित व्यवहार को प्राप्त करने के लिए क्या करना चाहिए?

अद्यतन यह इस प्रतीत होता है Windows के लिए संबंधित 7. सब कुछ Windows XP मोड में होने की उम्मीद के रूप में व्यवहार करता है। क्या कोई और विंडोज 7 चला रहा है मेरे कोड को आजमा सकता है और सत्यापित कर सकता है कि मैं पागल नहीं हूं?

+0

मैंने आपका कोड बिल्कुल लिया और इसे एक नए रूप में फेंक दिया और व्यवहार को पुन: उत्पन्न नहीं कर सकता। आप चयनित इंडेक्स चेंज किए गए ईवेंट को तारित करने का प्रयास कर सकते हैं और कुछ कंसोल संदेशों को फेंक सकते हैं और देख सकते हैं कि कॉम्बो में टाइप करते समय क्या हो रहा है। – TheHurt

+0

मैंने 'comboBox.SelectedIndexChanged + = new EventHandler (प्रतिनिधि {Console.WriteLine ("SelectedIndex = {0}", comboBox.SelectedIndex);});' और आउटपुट का कहना है कि 'चयनित इंडेक्स' को "2" में बदल दिया गया है और फिर "3" तक, जो 'टेक्स्टबॉक्स' दिखाता है उससे मेल खाता है। – Ecyrb

+0

यदि यह एक पुन: उत्पादित बग है, तो आपको इसे माइक्रोसॉफ्ट कनेक्ट पर सबमिट करना चाहिए: https://connect.microsoft.com/VisualStudio/ –

उत्तर

2

यह hotfix इस मुद्दे का समाधान होगा: अंत में मैं एक ComboBox उपवर्ग के रूप में अपने खुद के समाधान गिर गयी है।

+2

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। –

+1

वैसे यह माइक्रोसॉफ्ट द्वारा भेजे गए हॉटफिक्स के डाउनलोड पेज का लिंक है।यहां जोड़ने के लिए कुछ भी नहीं है और मुझे उम्मीद है कि यह लिंक समाप्त होने की उम्मीद नहीं है :) – bittusarkar

6

का संभावित हल DropDownStyleDropDown के लिए बदल किया जा सकता है और जोड़ने निम्नलिखित:

comboBox.Validating += new CancelEventHandler((o, e) => 
    { 
     e.Cancel = (comboBox.DataSource as string[]).Contains(comboBox.Text) == false; 
    }); 

कि उपयोगकर्ताओं को कुछ भी टाइप करने की अनुमति देगा, लेकिन यह उन्हें टैब दूर नहीं दूँगी नियंत्रण से जब तक कि वे एक वैध टाइप किया आइटम।

फिर भी, व्यवहार XP से बदल रहा है के साथ खुश नहीं विन 7.

+1

+1 यहां vb.net संस्करण है जो मेरे लिए काम करता है: 'e.Cancel = नहीं (comboBox.Items.Contains (comboBox.Text))'। –

0

मुझे पता है कि यह प्रतिक्रिया काफी पुराना है, लेकिन मैं यह विंडोज 7 बग के जवाब की जरूरत थी। मैं Ecyrb की नस में थोड़ी देर के लिए चारों ओर tinkered और साथ निम्नलिखित काम के आसपास आया था: जहां ComboBox स्थित है से

Me.KeyPreview = True 

: अनुप्रयोग के लिए

InitForm() से इस संपत्ति जोड़े

Private mbTab As Boolean 
Private miPrevIndex As Integer = -1 
Private Sub DropDownListEx_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Validating 
    miPrevIndex = Me.SelectedIndex 
    MyBase.OnSelectedIndexChanged(e) 
End Sub 
Private Sub DropDownListEx_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles Me.PreviewKeyDown 
    mbTab = e.KeyCode = Windows.Forms.Keys.Tab 
End Sub 
Protected Overrides Sub OnDropDownClosed(ByVal e As System.EventArgs) 
    MyBase.OnDropDownClosed(e) 
    If Me.SelectedIndex <> miPrevIndex Then 
     If mbTab = True Then 
      Me.SelectedIndex = miPrevIndex 
     Else 
      miPrevIndex = Me.SelectedIndex 
     End If 
     MyBase.OnSelectedIndexChanged(e) 
    End If 
End Sub 

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

0

OnTextChanged विधि ओवरराइड और बस आधार पर पर संदेश देना नहीं है।

protected override void OnTextChanged(EventArgs e) 
{ 
    //Eat the message so it doesn't select an incorrect value. 
} 
1

मैं अपने आप में भाग गया और कुछ कामकाज पाया।

//as noted here: https://connect.microsoft.com/VisualStudio/feedback/details/523272/combobox-does-not-display-selectedvalue-to-user-in-windows-7 
//Windows 7 has issues with ComboBoxStyle.DropDownList mixed with AutoCompleteMode.Append or AutoCompleteMode.SuggestAppend 
//this class seeks to address those problems 
public class BetterComboBox : ComboBox 
{ 
    private int _windows7CorrectedSelectedIndex = -1; 

    private int? _selectedIndexWhenDroppedDown = null; 
    protected override void OnDropDown(EventArgs e) 
    { 
    _selectedIndexWhenDroppedDown = SelectedIndex; 
    base.OnDropDown(e); 
    } 
    private bool _onDropDownClosedProcessing = false; 
    protected override void OnDropDownClosed(EventArgs e) 
    { 
    if (_selectedIndexWhenDroppedDown != null && _selectedIndexWhenDroppedDown != SelectedIndex) 
    { 
     try 
     { 
     _onDropDownClosedProcessing = true; 
     OnSelectionChangeCommitted(e); 
     } 
     finally 
     { 
     _onDropDownClosedProcessing = false; 
     } 
    } 
    base.OnDropDownClosed(e); 
    if (SelectedIndex != _windows7CorrectedSelectedIndex) 
    { 
     SelectedIndex = _windows7CorrectedSelectedIndex; 
     OnSelectionChangeCommitted(e); 
    } 
    } 
    protected override void OnSelectionChangeCommitted(EventArgs e) 
    { 
    if (!_onDropDownClosedProcessing) _windows7CorrectedSelectedIndex = SelectedIndex; 
    _selectedIndexWhenDroppedDown = null; 
    base.OnSelectionChangeCommitted(e); 
    } 
    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
    bool alreadyMatched = true; 
    if (_windows7CorrectedSelectedIndex != SelectedIndex) 
    { 
     _windows7CorrectedSelectedIndex = SelectedIndex; 
     alreadyMatched = false; 
    } 
    base.OnSelectedIndexChanged(e); 

    //when not dropped down, the SelectionChangeCommitted event does not fire upon non-arrow keystrokes due (I suppose) to AutoComplete behavior 
    //this is not acceptable for my needs, and so I have come up with the best way to determine when to raise the event, without causing duplication of the event (alreadyMatched) 
    //and without causing the event to fire when programmatic changes cause SelectedIndexChanged to be raised (_processingKeyEventArgs implies user-caused) 
    if (!DroppedDown && !alreadyMatched && _processingKeyEventArgs) OnSelectionChangeCommitted(e); 
    } 
    private bool _processingKeyEventArgs = false; 
    protected override bool ProcessKeyEventArgs(ref Message m) 
    { 
    try 
    { 
     _processingKeyEventArgs = true; 
     return base.ProcessKeyEventArgs(ref m); 
    } 
    finally 
    { 
     _processingKeyEventArgs = false; 
    } 
    } 
} 
1

मैंने अपना स्वयं का समाधान बनाया क्योंकि मुझे नहीं लगता था कि सभी उपयोगकर्ताओं के लिए हॉटफिक्स को तैनात करना उचित या प्रबंधनीय था। हालांकि हॉटफिक्स समस्या विवरण मेरी समस्या का वर्णन करता है। उदाहरण के लिए नीचे दी गई सूची देखें:

शाहबलूतिक एप्पल
बुरा
बिस्तर
ईंट
पनीर

मैं एक आइटम ऐसे बिस्तर के रूप में बी के साथ शुरू का चयन करता हूं, तो यह पहली बार के साथ शुरू का चयन करेंगे बी जो खराब होगा। यह है कि अगर मैं केवल पहले दो अक्षर टाइप करता हूं (मेरी असली दुनिया के मामले के रूप में संपूर्ण स्ट्रिंग टाइप करने का परीक्षण नहीं किया गया है तो उपयोगकर्ता ऐसा करने के लिए अनुचित होगा)। - SuggestAppend,
AutoCompleteSource - ListItems,
DropDownStyle - DropDownList
AutoCompleteMode:

मैं निम्नलिखित सेटिंग्स के साथ कोई ComboBox है।

समस्या को हल करने के लिए मैंने निम्न कार्य किया क्योंकि मैंने देखा कि मेरा वांछित मान चयनित इंडेक्स चेंज किए गए ईवेंट के दौरान चुना गया था लेकिन छोड़ने की घटना नहीं।

int myDesiredIndexSelection; 

    private void myComboBox_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     myDesiredIndexSelection = myComboBox.SelectedIndex; 
    } 

    private void myComboBox_Leave(object sender, EventArgs e) 
    { 
     myComboBox.SelectedIndex = myDesiredIndexSelection; 
    } 
    private void myForm_KeyUp(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Tab) 
      myComboBox.SelectedIndex = myDesiredIndexSelection; 
    } 

छोड़ने की घटना एंटर कुंजी को मारने का पता लगती है। कुंजीअप (KeyDown काम नहीं किया) टैब समस्या को ठीक करने लग रहा था।

0

मैं अभी भी इसे विंडोज 10 पर पुन: उत्पन्न कर सकता हूं, इसलिए मैंने सोचा कि मैं सूची में अपना कामकाज जोड़ूंगा।

Private Sub LeaveComboBox(s As Object, e As EventArgs) Handles ComboBox1.Leave 
    Dim sender as ComboBox = DirectCast(s, ComboBox) 

    If sender.DroppedDown Then 
     ' Save the correct item 
     Dim correctSelection as Object = sender.SelectedItem 

     ' The core of the issue seems to be that while searching, Leave is 
     ' triggered before DropDownClosed when you hit the TAB. 
     ' Instead, trigger that now: 
     sender.DroppedDown = False 

     ' Restore the correct item. 
     sender.SelectedItem = correctSelection 
    End If 
End Sub 
संबंधित मुद्दे