performance - WPF editable combobox slow typing -


i have wpf combobox :

<combobox x:name="customercombobox" iseditable="true" itemssource="{binding relations.view}" displaymemberpath="model.sname" />

if click in editable combo while binding in place (mvvm) give focus, , press , hold key, assume combo filled key rather quickly, isn't. if remove displaymemberpath , same, have expected behavior. of course need binding.

the performance penalty shows when combo has lot of elements mine has 6000.

i cannot understand performance penalty coming from. there way bypass problem ?

below code solves issues creating specialised combobox caches binding results. created looking @ orginal source code of combobox , itemscontrol using .net reflector.

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<string> _completionstrings = new list<string>();         private int _textboxselectionstart;         private bool _updatingtext;         private bool _updatingselecteditem;         private static dictionary<textbox, fasteditcombobox> _textboxdictionary = new dictionary<textbox,fasteditcombobox>();          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         {                         {                 return (string)base.getvalue(textproperty);             }             set             {                 base.setvalue(textproperty, value);             }         }          public override void onapplytemplate()         {             base.onapplytemplate();             _textboxpart = base.gettemplatechild("part_editabletextbox") 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 && !_updatingselecteditem)             {                 try                 {                     _updatingtext = true;                     if (base.istextsearchenabled)                     {                         int num = findmatchingprefix(newtext);                         if (num >= 0)                         {                             if (textboxupdated)                             {                                 int selectionstart = this._textboxpart.selectionstart;                                 if ((selectionstart == newtext.length) && (selectionstart > 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;                     }                 }                                 {                     _updatingtext = false;                 }             }         }          internal void selecteditemupdated()         {             try             {                 this._updatingselecteditem = true;                 if (!this._updatingtext)                 {                     string primarytextfromitem = getprimarytextfromitem(selecteditem);                     text = primarytextfromitem;                 }                 this.update();             }                         {                 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) && (this._textboxpart.text != text))                     {                         this._textboxpart.text = text;                         this._textboxpart.selectall();                     }                 }                                 {                     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 >= 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 < 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 >= 0) _completionstrings.removeat(index);         }          private static void ontextchanged(object sender, textchangedeventargs e)         {             textbox tb = e.source 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 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);         }     } } 

selecting first element clears selection implementation. still bugs here


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -