Hi All
This isn’t a question, but thought I would share a solution I have for creating a searchable WiseJ.Web.ComboBox. I have seen this asked once or twice, and would probably work for WinForms as well (untested). The idea is that you should be able to pass a class, define which fields to display and which to use as value/key. Some other minor features like limiting to the list and whether or not to populate the list on startup.
This is not all my own source, I have used part of Frank’s SearchTextBox (https://wisej.com/support/question/how-autocomplete-search-boxcontrol-from-httpwisej-comsupport-is-implemented) and Max Lambertini’s ideas (https://stackoverflow.com/questions/11780558/c-sharp-winforms-combobox-dynamic-autocomplete) to gather the ideas and create a control that is similar in functionality to the JQuery AutoComplete.
To use you will need to have a TextBox to capture the Id (this can be hidden) on your page. The Text box can just capture the same text as the ComboBox, but the idea is that you would generally use a KeyValuePair.
You simply drop the control where you need it and in your code you call the ComboboxName.Set() when initialising the Combo, or alternatively the ComboboxName.MakeTheMagicHappen() if all the public variables are already set. This works best when using standard “DropDown” as the ComboBox DropDownStyle.
Hope this helps someone and that they can use. (See Answer for Full code – and excuse my coding style, I still have lots to learn)
Regards
Kevin Caine
253 Technologies and KLEVA
using System; using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.Linq; using Wisej.Web; namespace MyApp.CustomControls { public class SearchComboBox : Wisej.Web.ComboBox { public int minLength { get; set; } public dynamic obj { get; set; } public string displayField { get; set; } public string valueField { get; set; } public bool limitToList { get; set; } public TextBox idTextBox { get; set; } public string defaultId { get; set; } public bool showInitialList { get; set; } public SearchComboBoxType searchType { get; set; } private string[] data { get; set; } private bool found { get; set; } public SearchComboBox() { this.KeyUp += SearchComboBox_KeyUp; this.TextChanged += SearchComboBox_TextChanged; this.Leave += SearchComboBox_Leave; } public void Set(dynamic ClassList, TextBox TextBoxForIdField, string DisplayItem, string IdItem = "", int MinimumLengthBeforeSearch = 2, bool LimitToList = true, bool ShowInitialList = true, string DefaultIdFieldValue = "0", SearchComboBoxType SearchComboBoxType = SearchComboBoxType.Contains){ obj = ClassList; idTextBox = TextBoxForIdField; displayField = DisplayItem; if (IdItem == "") { valueField = DisplayItem; } else { valueField = IdItem; } minLength = MinimumLengthBeforeSearch; limitToList = LimitToList; defaultId = DefaultIdFieldValue; showInitialList = ShowInitialList; searchType = SearchComboBoxType; MakeTheMagicHappen(); } public void MakeTheMagicHappen() { int cnt = obj.Count; data = new string[cnt]; for (int i = 0; i < cnt; i++) { var changedItem = ToExpandoObject(obj[i]); var dictItem = changedItem as IDictionary<string, object>; data[i] = dictItem[displayField].ToString(); } idTextBox.Text = defaultId; if (showInitialList) { ComboFill(obj, valueField, displayField); } } private void SearchComboBox_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Back) { int sStart = this.SelectionStart; if (sStart > 0) { sStart--; if (sStart == 0) { this.Text = defaultId; } else { this.Text = this.Text.Substring(0, sStart); } } e.Handled = true; } } private void SearchComboBox_TextChanged(object sender, EventArgs e) { HandleTextChanged(); found = false; foreach (var o in obj) { if (o.Name == this.Text) { idTextBox.Text = o.Id.ToString(); found = true; break; } } if (!found) { idTextBox.Text = defaultId; } } private void HandleTextChanged() { var txt = this.Text; if (txt.Length > (minLength - 1)) { IEnumerable<string> list = null; switch (searchType) { case SearchComboBoxType.Contains: list = from d in data where d.ToUpper().Contains(this.Text.ToUpper()) select d; break; case SearchComboBoxType.StartOnly: list = from d in data where d.ToUpper().StartsWith(this.Text.ToUpper()) select d; break; case SearchComboBoxType.EndOnly: list = from d in data where d.ToUpper().EndsWith(this.Text.ToUpper()) select d; break; } if (list.Count() > 0) { this.DataSource = list.ToList(); var sText = this.Items[0].ToString(); this.SelectionStart = txt.Length; this.SelectionLength = sText.Length - txt.Length; this.DroppedDown = true; return; } else { this.DroppedDown = false; this.SelectionStart = txt.Length; } } } private void SearchComboBox_Leave(object sender, EventArgs e) { if (limitToList) { if (!found || idTextBox.Text == defaultId) { this.Text = ""; } } } // Helpers private ExpandoObject ToExpandoObject(object obj) { IDictionary<string, object> newObj = new ExpandoObject(); foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(obj.GetType())) { newObj.Add(property.Name, property.GetValue(obj)); } return (ExpandoObject)newObj; } private void ComboFill(IEnumerable<dynamic> dynObject, string valueField, string txtField = "") { List<KeyValuePair<string, string>> cboList = new List<KeyValuePair<string, string>>(); if (dynObject != null && dynObject.Count() > 0) { cboList.Add(new KeyValuePair<string, string>(defaultId, "")); string dbFields = valueField; if (txtField != "") { dbFields += "," + txtField; } try { foreach (dynamic item in dynObject) { var changedItem = ToExpandoObject(item); var dictItem = changedItem as IDictionary<string, object>; string key = dictItem[valueField].ToString(); string value = key; if (txtField != "") { value = dictItem[txtField].ToString(); } cboList.Add(new KeyValuePair<string, string>(key, value)); } } catch { // Well dammit - something didn't work! } } else { cboList.Add(new KeyValuePair<string, string>(valueField, txtField)); } this.ValueMember = "key"; this.DisplayMember = "value"; this.DataSource = cboList; } public enum SearchComboBoxType { Contains = 0, StartOnly = 1, EndOnly = 2 } } }
Please login first to submit.