Good afternoon / evening, faced with the task of making a contextual search in Windows.Controls.ComboBox. Search is made on any occurrence. For example, we have: Vasya, Fedya, Vika We type "in", we get: Vasya, Vika; "va" remains Vasya; "dya" - Fedya. I hope the meaning is clear. Modified the ComboBox class:

using System.Collections.Generic; using System.Linq; using System.Windows.Controls; using ProgrammingWeapons; namespace Telemetria.UI { public class ComboBoxFinder : ComboBox { private bool _isAutoFilter = true; public bool IsAutoFilter { get { return _isAutoFilter; } set { _isAutoFilter = value; } } private readonly List<object> _fullList; private string _filterText { get; set; } public ComboBoxFinder() { IsTextSearchEnabled = false; // отключение автовыбора первого элемента, иначе не работает поиск _fullList = new List<object>(); _filterText = ""; KeyUp += (sender, args) => Filter(Text); KeyDown += (sender, args) => { if (_isAutoFilter) IsDropDownOpen = true; Filter(Text); }; SelectionChanged += (sender, args) => { //if(SelectedItem != null) Filter(""); }; } public void Filter(string text) { if (!_isAutoFilter) return; if (text.IsNull()) return; _filterText = text; if (_fullList.Count < 1) foreach (var isc in Items.SourceCollection) _fullList.Add(isc); var tmpSourceList = _fullList.Where(fl => fl != null && fl.ToString().ToUpper().Contains(_filterText.ToUpper())).ToList(); //if (tmpSourceList.Count == 1) return; ItemsSource = tmpSourceList; } } } 

It seems that what is needed is done, but it works somehow crookedly. When you select the element for the first time, the element is displayed in the header, I start typing for the second search, the first letter is printed and then disappears, you need to enter it again, after which everything is filtered normally. Or the second option when you try to print the text pops up the selected item and the data is not filtered.

What error when appears yet I will not understand. Tell me where to look. WinForms can not be used, because does not fit into the project. On the Internet, I did not find anything, it seems that everyone writes under WinForms (

  • Apparently, except for me, no one came across this. I leave it for now, let it work until the necessary thought comes - DennerV
  • For some reason you are trying to work at the View level. It does not look very correct. In any case, everything is somehow complicated for you, why not through ItemsSource / Filter? - VladD

1 answer 1

It works for me like this:

XAML:

 <ComboBox ItemsSource="{Binding}" x:Name="CB" TextBoxBase.TextChanged="OnComboboxTextChanged" IsTextSearchEnabled="False" IsEditable="True" VerticalAlignment="Top"/> 

Code-behind:

 void OnComboboxTextChanged(object sender, RoutedEventArgs e) { CB.IsDropDownOpen = true; // убрать selection, если dropdown только открылся var tb = (TextBox)e.OriginalSource; tb.Select(tb.SelectionStart + tb.SelectionLength, 0); CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(CB.ItemsSource); cv.Filter = s => ((string)s).IndexOf(CB.Text, StringComparison.CurrentCultureIgnoreCase) >= 0; } 

Result:

Animation Everyone loves anima.