Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Below code solves the issues by creating a specialised combobox that basically caches all binding results. I created it by looking at the orginal source code of the combobox and itemscontrol using .NET reflector.</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Reflection; using System.ComponentModel; using System.Collections.ObjectModel; using System.Windows.Controls.Primitives; using System.Collections; namespace ICeTechControlLibrary { public class FastEditComboBox : ComboBox { //PARTS private TextBox _TextBoxPart = null; //DEPENDENCY PROPERTIES public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteTextBox), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(FastEditComboBox.OnTextChanged))); private List&lt;string&gt; _CompletionStrings = new List&lt;string&gt;(); private int _textBoxSelectionStart; private bool _updatingText; private bool _updatingSelectedItem; private static Dictionary&lt;TextBox, FastEditComboBox&gt; _TextBoxDictionary = new Dictionary&lt;TextBox,FastEditComboBox&gt;(); static FastEditComboBox() { EventManager.RegisterClassHandler(typeof(TextBox), TextBox.TextChangedEvent, new TextChangedEventHandler(FastEditComboBox.OnTextChanged)); EventManager.RegisterClassHandler(typeof(TextBox), TextBox.SelectionChangedEvent, new RoutedEventHandler(FastEditComboBox.OnSelectionChanged)); } public string Text { get { return (string)base.GetValue(TextProperty); } set { base.SetValue(TextProperty, value); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); _TextBoxPart = base.GetTemplateChild("PART_EditableTextBox") as TextBox; if (!_TextBoxDictionary.ContainsKey(_TextBoxPart)) _TextBoxDictionary.Add(_TextBoxPart, this); } private void OnTextBoxSelectionChanged(object sender, RoutedEventArgs e) { this._textBoxSelectionStart = this._TextBoxPart.SelectionStart; } private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) { if (IsEditable) { TextUpdated(_TextBoxPart.Text, true); } } private void TextUpdated(string newText, bool textBoxUpdated) { if (!_updatingText &amp;&amp; !_updatingSelectedItem) { try { _updatingText = true; if (base.IsTextSearchEnabled) { int num = FindMatchingPrefix(newText); if (num &gt;= 0) { if (textBoxUpdated) { int selectionStart = this._TextBoxPart.SelectionStart; if ((selectionStart == newText.Length) &amp;&amp; (selectionStart &gt; this._textBoxSelectionStart)) { string primaryTextFromItem = _CompletionStrings[num]; this._TextBoxPart.Text = primaryTextFromItem; this._TextBoxPart.SelectionStart = newText.Length; this._TextBoxPart.SelectionLength = primaryTextFromItem.Length - newText.Length; newText = primaryTextFromItem; } } else { string b = _CompletionStrings[num]; if (!string.Equals(newText, b, StringComparison.CurrentCulture)) { num = -1; } } } if (num != base.SelectedIndex) { SelectedIndex = num; } } if (textBoxUpdated) { Text = newText; } else if (_TextBoxPart != null) { _TextBoxPart.Text = newText; } } finally { _updatingText = false; } } } internal void SelectedItemUpdated() { try { this._updatingSelectedItem = true; if (!this._updatingText) { string primaryTextFromItem = GetPrimaryTextFromItem(SelectedItem); Text = primaryTextFromItem; } this.Update(); } finally { this._updatingSelectedItem = false; } } private void Update() { if (this.IsEditable) { this.UpdateEditableTextBox(); } else { //this.UpdateSelectionBoxItem(); } } private void UpdateEditableTextBox() { if (!_updatingText) { try { this._updatingText = true; string text = this.Text; if ((this._TextBoxPart != null) &amp;&amp; (this._TextBoxPart.Text != text)) { this._TextBoxPart.Text = text; this._TextBoxPart.SelectAll(); } } finally { this._updatingText = false; } } } protected override void OnSelectionChanged(SelectionChangedEventArgs e) { base.RaiseEvent(e); this.SelectedItemUpdated(); if (this.IsDropDownOpen) { object Item = SelectedItem; if (Item != null) { base.OnSelectionChanged(e); } //object internalSelectedItem = base.InternalSelectedItem; //if (internalSelectedItem != null) //{ // base.NavigateToItem(internalSelectedItem, ItemsControl.ItemNavigateArgs.Empty); //} } } int FindMatchingPrefix(string s) { int index = _CompletionStrings.BinarySearch(s, StringComparer.OrdinalIgnoreCase); if (index &gt;= 0) return index; index = ~index; string p = _CompletionStrings[index]; if (p.StartsWith(s, StringComparison.CurrentCultureIgnoreCase)) return index; return -1; } protected override void OnDisplayMemberPathChanged(string oldDisplayMemberPath, string newDisplayMemberPath) { FillCompletionStrings(); } protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { base.OnItemsChanged(e); switch (e.Action) { case System.Collections.Specialized.NotifyCollectionChangedAction.Add: AddCompletionStrings(e.NewItems); break; case System.Collections.Specialized.NotifyCollectionChangedAction.Remove: RemoveCompletionStrings(e.OldItems); break; case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: FillCompletionStrings(); break; } } private void FillCompletionStrings() { _CompletionStrings.Clear(); AddCompletionStrings(Items); } private void RemoveCompletionStrings(IList items) { foreach (object o in items) { RemoveCompletionStringForItem(o); } } private void AddCompletionStrings(IList items) { foreach (object o in items) { AddCompletionStringForItem(o); } } private void AddCompletionStringForItem(object item) { Binding binding = new Binding(DisplayMemberPath); TextBlock tb = new TextBlock(); tb.DataContext = item; tb.SetBinding(TextBlock.TextProperty, binding); string s = tb.Text; int index = _CompletionStrings.BinarySearch(s, StringComparer.OrdinalIgnoreCase); if (index &lt; 0) { _CompletionStrings.Insert(~index, s); } else { _CompletionStrings.Insert(index, s); } } private string GetPrimaryTextFromItem(object item) { Binding binding = new Binding(DisplayMemberPath); TextBlock tb = new TextBlock(); tb.DataContext = item; tb.SetBinding(TextBlock.TextProperty, binding); string s = tb.Text; return s; } private void RemoveCompletionStringForItem(object item) { Binding binding = new Binding(DisplayMemberPath); TextBlock tb = new TextBlock(); tb.DataContext = item; tb.SetBinding(TextBlock.TextProperty, binding); string s = tb.Text; int index = _CompletionStrings.BinarySearch(s, StringComparer.OrdinalIgnoreCase); if (index &gt;= 0) _CompletionStrings.RemoveAt(index); } private static void OnTextChanged(object sender, TextChangedEventArgs e) { TextBox tb = e.Source as TextBox; if (tb.Name == "PART_EditableTextBox") { if (_TextBoxDictionary.ContainsKey(tb)) { FastEditComboBox combo = _TextBoxDictionary[tb]; combo.OnTextBoxTextChanged(sender, e); e.Handled = true; } } } private static void OnSelectionChanged(object sender, RoutedEventArgs e) { TextBox tb = e.Source as TextBox; if (tb.Name == "PART_EditableTextBox") { if (_TextBoxDictionary.ContainsKey(tb)) { FastEditComboBox combo = _TextBoxDictionary[tb]; combo.OnTextBoxSelectionChanged(sender, e); e.Handled = true; } } } private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { FastEditComboBox actb = (FastEditComboBox)d; actb.TextUpdated((string)e.NewValue, false); } } } </code></pre> <p>selecting the very first element clears the selection with this implementation. so still some bugs here</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload