2012-08-02 17 views
12

मेरी समस्या इस के समान है: How can I dynamically change auto complete entries in a C# combobox or textbox? लेकिन मुझे अभी भी समाधान नहीं मिला है।सी # Winforms combobox गतिशील स्वत: पूर्ण

संक्षेप में समस्या:

मैं एक ComboBox है और रिकॉर्ड की एक बड़ी संख्या में यह दिखाने के लिए। जब उपयोगकर्ता टाइपिंग शुरू करता है तो मैं इनपुट लोड के साथ शुरू होने वाले रिकॉर्ड लोड करना चाहता हूं और उपयोगकर्ता को स्वत: पूर्ण करने की पेशकश करता हूं। ऊपर दिए गए विषय में वर्णित अनुसार मैं उन्हें сomboBox_TextChanged पर लोड नहीं कर सकता क्योंकि मैं हमेशा पिछले परिणामों को ओवरराइट करता हूं और उन्हें कभी नहीं देखता।

क्या मैं इसे केवल ComboBox का उपयोग करके कार्यान्वित कर सकता हूं?

сomboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend; 
сomboBox.AutoCompleteSource = AutoCompleteSource.CustomSource; 
+1

आप jQuery या ajax के माध्यम से यह कर सकते हैं।एक स्ट्रिंग में लगने वाली विधि बनाएं और उस स्ट्रिंग से मेल खाने वाले परिणामों की एक सूची लौटाएं, फिर कीस्ट्रोक को सुनने के लिए jquery/AJAX को हुक अप करें और कीस्ट्रोक की एक्स संख्या (आमतौर पर 3) के बाद, jquery विधि को कॉल करें और परिणामों के साथ सूची पॉप्युलेट करें। – Brian

+6

हम्म ... यह Winform – algreat

+0

पर है क्षमा करें, मुझे वेब पर ध्यान केंद्रित करना है लेकिन अवधारणा वही है। एक ऐसा ईवेंट है जो कीस्ट्रोक के लिए सुनता है और एक विधि को कॉल करता है जो स्ट्रिंग लेता है और परिणाम सेट देता है। – Brian

उत्तर

13

यहाँ मेरा अंतिम समाधान है। यह बड़ी मात्रा में डेटा के साथ ठीक काम करता है। मैं यह सुनिश्चित करने के लिए Timer का उपयोग करता हूं कि उपयोगकर्ता वर्तमान मूल्य ढूंढना चाहता है। यह जटिल दिखता है लेकिन यह नहीं करता है। विचार के लिए मैक्स लैम्बर्टिनी के लिए धन्यवाद।

 private bool _canUpdate = true; 

     private bool _needUpdate = false;  

     //If text has been changed then start timer 
     //If the user doesn't change text while the timer runs then start search 
     private void combobox1_TextChanged(object sender, EventArgs e) 
     { 
      if (_needUpdate) 
      { 
       if (_canUpdate) 
       { 
        _canUpdate = false; 
        UpdateData();     
       } 
       else 
       { 
        RestartTimer(); 
       } 
      } 
     } 

     private void UpdateData() 
     { 
      if (combobox1.Text.Length > 1) 
      { 
       List<string> searchData = Search.GetData(combobox1.Text); 
       HandleTextChanged(searchData); 
      } 
     }  

     //If an item was selected don't start new search 
     private void combobox1_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      _needUpdate = false; 
     } 

     //Update data only when the user (not program) change something 
     private void combobox1_TextUpdate(object sender, EventArgs e) 
     { 
      _needUpdate = true; 
     } 

     //While timer is running don't start search 
     //timer1.Interval = 1500; 
     private void RestartTimer() 
     { 
      timer1.Stop(); 
      _canUpdate = false; 
      timer1.Start(); 
     } 

     //Update data when timer stops 
     private void timer1_Tick(object sender, EventArgs e) 
     { 
      _canUpdate = true; 
      timer1.Stop(); 
      UpdateData(); 
     } 

     //Update combobox with new data 
     private void HandleTextChanged(List<string> dataSource) 
     { 
      var text = combobox1.Text; 

      if (dataSource.Count() > 0) 
      { 
       combobox1.DataSource = dataSource; 

       var sText = combobox1.Items[0].ToString(); 
       combobox1.SelectionStart = text.Length; 
       combobox1.SelectionLength = sText.Length - text.Length; 
       combobox1.DroppedDown = true; 


       return; 
      } 
      else 
      { 
       combobox1.DroppedDown = false; 
       combobox1.SelectionStart = text.Length; 
      } 
     } 

यह समाधान बहुत अच्छा नहीं है। तो अगर किसी के पास कोई अन्य समाधान है तो कृपया इसे मेरे साथ साझा करें।

+4

यदि - मुझे पसंद है - आपको लगता है कि "combobox1.DroppedDown = true" का उपयोग करके माउस कर्सर गायब हो जाता है "इसके बाद कर्सर। कंटेंट = कर्सर। डीफॉल्ट"। – Andy

+0

नाम 'खोज' वर्तमान संदर्भ \t में मौजूद नहीं है। मुझे यहां क्या समझ नहीं आ रहा है? –

+1

खोज डेटास्रोत –

7

हाँ, आप निश्चित रूप से कर सकते हैं ... लेकिन यह कुछ काम यह समेकित रूप से काम करने की जरूरत: (नहीं TextBox या ListBox)

मैं इस सेटिंग का उपयोग करें। यह कुछ कोड है जिसके साथ मैं आया था। ध्यान रखें कि यह उपयोग बता गया के स्वत: पूर्ण सुविधाओं नहीं करता है, और यह काफी धीमी गति से हो सकता है अगर आप इसका इस्तेमाल बहुत से आइटम के माध्यम से जांचने की ...

string[] data = new string[] { 
    "Absecon","Abstracta","Abundantia","Academia","Acadiau","Acamas", 
    "Ackerman","Ackley","Ackworth","Acomita","Aconcagua","Acton","Acushnet", 
    "Acworth","Ada","Ada","Adair","Adairs","Adair","Adak","Adalberta","Adamkrafft", 
    "Adams" 

}; 
public Form1() 
{ 
    InitializeComponent(); 
} 

private void comboBox1_TextChanged(object sender, EventArgs e) 
{ 
    HandleTextChanged(); 
} 

private void HandleTextChanged() 
{ 
    var txt = comboBox1.Text; 
    var list = from d in data 
       where d.ToUpper().StartsWith(comboBox1.Text.ToUpper()) 
       select d; 
    if (list.Count() > 0) 
    { 
     comboBox1.DataSource = list.ToList(); 
     //comboBox1.SelectedIndex = 0; 
     var sText = comboBox1.Items[0].ToString(); 
     comboBox1.SelectionStart = txt.Length; 
     comboBox1.SelectionLength = sText.Length - txt.Length; 
     comboBox1.DroppedDown = true; 
     return; 
    } 
    else 
    { 
     comboBox1.DroppedDown = false; 
     comboBox1.SelectionStart = txt.Length; 
    } 
} 

private void comboBox1_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Back) 
    { 
     int sStart = comboBox1.SelectionStart; 
     if (sStart > 0) 
     { 
      sStart--; 
      if (sStart == 0) 
      { 
       comboBox1.Text = ""; 
      } 
      else 
      { 
       comboBox1.Text = comboBox1.Text.Substring(0, sStart); 
      } 
     } 
     e.Handled = true; 
    } 
} 
+0

यह ठीक समाधान है। यह डिफ़ॉल्ट स्वत: पूर्ण से बेहतर काम करता है। लेकिन यह अभी भी बड़ी मात्रा में डेटा के लिए पर्याप्त नहीं है। तो मैं आपके समाधान को बेहतर बनाने की कोशिश करूंगा। – algreat

+1

आप केवल डेटा पर क्वेरी शुरू करके स्वत: पूर्ण ट्रिगर कर सकते हैं, कहें, टेक्स्ट लम्बाई तीन से अधिक है, चार वर्ण ... –

+0

टाइमआउट का उपयोग करें, मुझे लगता है कि एक अच्छा विकल्प है, जब उपयोगकर्ता पूर्वनिर्धारित समय के बाद टाइपिंग बंद कर देता है, तो शुरू होता है क्वेरी करें। – Joseph

2

यह कोड आपके फॉर्म लोड पर लिखता है। यह डेटाबेस में सभी टूर प्रदर्शित करता है जब उपयोगकर्ता कॉम्बो बॉक्स में अक्षर टाइप करता है। यह कोड स्वचालित रूप से उपयोगकर्ता के अनुसार सही विकल्प का सुझाव देता है और जोड़ता है।

  con.Open(); 
      cmd = new SqlCommand("SELECT DISTINCT Tour FROM DetailsTB", con); 
      SqlDataReader sdr = cmd.ExecuteReader(); 
      DataTable dt = new DataTable(); 
      dt.Load(sdr); 
      combo_search2.DisplayMember = "Tour"; 
      combo_search2.DroppedDown = true; 

      List<string> list = new List<string>(); 
      foreach (DataRow row in dt.Rows) 
      { 
       list.Add(row.Field<string>("Tour")); 
      } 
      this.combo_search2.Items.AddRange(list.ToArray<string>()); 
      combo_search2.AutoCompleteMode = AutoCompleteMode.SuggestAppend; 
      combo_search2.AutoCompleteSource = AutoCompleteSource.ListItems; 
      con.Close(); 
0
using (var client = new UserServicesClient()) 
{ 
    var list = new AutoCompleteStringCollection(); 
    list.AddRange(client.ListNames(query).ToArray()); 
    comboBoxName.AutoCompleteCustomSource = list; 
} 
+1

प्राप्त करने के लिए उपयोगकर्ता परिभाषित फ़ंक्शन है आम तौर पर, यदि कोड का उद्देश्य क्या है, और यह दूसरों को पेश किए बिना समस्या का हल क्यों करता है, तो इसका उत्तर अधिक उपयोगी होता है। (इस पोस्ट को कम से कम एक उपयोगकर्ता द्वारा ध्वजांकित किया गया था, संभवतः क्योंकि उन्होंने सोचा था कि स्पष्टीकरण के बिना उत्तर हटा दिया जाना चाहिए।) –

2

पिछले जवाब में कमियां हैं।

private ConnectSqlForm() 
    { 
     InitializeComponent(); 
     cmbDatabases.TextChanged += UpdateAutoCompleteComboBox; 
     cmbDatabases.KeyDown += AutoCompleteComboBoxKeyPress; 
    } 

    private void UpdateAutoCompleteComboBox(object sender, EventArgs e) 
    { 
     var comboBox = sender as ComboBox; 
     if(comboBox == null) 
     return; 
     string txt = comboBox.Text; 
     string foundItem = String.Empty; 
     foreach(string item in comboBox.Items) 
      if (!String.IsNullOrEmpty(txt) && item.ToLower().StartsWith(txt.ToLower())) 
      { 
       foundItem = item; 
       break; 
      } 

     if (!String.IsNullOrEmpty(foundItem)) 
     { 
      if (String.IsNullOrEmpty(txt) || !txt.Equals(foundItem)) 
      { 
       comboBox.TextChanged -= UpdateAutoCompleteComboBox; 
       comboBox.Text = foundItem; 
       comboBox.DroppedDown = true; 
       Cursor.Current = Cursors.Default; 
       comboBox.TextChanged += UpdateAutoCompleteComboBox; 
      } 

      comboBox.SelectionStart = txt.Length; 
      comboBox.SelectionLength = foundItem.Length - txt.Length; 
     } 
     else 
      comboBox.DroppedDown = false; 
    } 

    private void AutoCompleteComboBoxKeyPress(object sender, KeyEventArgs e) 
    { 
     var comboBox = sender as ComboBox; 
     if (comboBox != null && comboBox.DroppedDown) 
     { 
      switch (e.KeyCode) 
      { 
       case Keys.Back: 
        int sStart = comboBox.SelectionStart; 
        if (sStart > 0) 
        { 
         sStart--; 
         comboBox.Text = sStart == 0 ? "" : comboBox.Text.Substring(0, sStart); 
        } 
        e.SuppressKeyPress = true; 
        break; 
      } 

     } 
    } 
2

मैं मैक्स Lambertini का जवाब बहुत मददगार मिल गया है, लेकिन इस तरह के रूप में अपने HandleTextChanged विधि को संशोधित किया है::

//I like min length set to 3, to not give too many options 
    //after the first character or two the user types 
    public Int32 AutoCompleteMinLength {get; set;} 

    private void HandleTextChanged() { 
     var txt = comboBox.Text; 
     if (txt.Length < AutoCompleteMinLength) 
      return; 

     //The GetMatches method can be whatever you need to filter 
     //table rows or some other data source based on the typed text. 
     var matches = GetMatches(comboBox.Text.ToUpper()); 

     if (matches.Count() > 0) { 
      //The inside of this if block has been changed to allow 
      //users to continue typing after the auto-complete results 
      //are found. 
      comboBox.Items.Clear(); 
      comboBox.Items.AddRange(matches); 
      comboBox.DroppedDown = true; 
      Cursor.Current = Cursors.Default; 
      comboBox.Select(txt.Length, 0); 
      return; 
     } 
     else { 
      comboBox.DroppedDown = false; 
      comboBox.SelectionStart = txt.Length; 
     } 
    } 
1

मैं इच्छित आइटम ड्रॉप डाउन सूची में चयन के साथ अपने स्वयं के संस्करण प्रदान करता है कुछ इस तरह ....

private void frmMain_Load(object sender, EventArgs e) 
{ 
    cboFromCurrency.Items.Clear(); 
    cboComboBox1.AutoCompleteMode = AutoCompleteMode.Suggest; 
    cboComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems; 
    // Load data in comboBox => cboComboBox1.DataSource = ..... 
    // Other things 
} 

private void cboComboBox1_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    cboComboBox1.DroppedDown = false; 
} 

सब (वाई) है कि

12

मैं इसके अलावा एसी आ लिखा था हाल ही में इस तरह की आवश्यकताओं को पार करें। मैंने नीचे दिए गए गुणों को उस कोड को लिखने के साथ सेट किया है जो यह काम करता है। अगर यह आपकी मदद करता है।

enter image description here

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