mvvm - Encountering lag in WPF Tab Control when switching between tabs (new instance of view is created each time I switch tabs) -


i beginner wpf, , having lot of learning while coding, please bear me. have searched archives, , couldn't find answer fits question.

i have view contains tab control, loaded 2 default tabs, , additional tabs added , removed programmatically based on user actions.

the way having observable collection of viewmodels different types of views can add , remove.

in xaml view, had few different datatemplates used determine kind of view load.

the issue i'm facing when click 1 tab another, seeing lag - close 1 second. put break point in code behind view, , noticed initializecomponent() method being called view every time click on tab.

the collection of viewmodels called activecontents, holds items of type activecontent. activecontent class 1 created, , contains object named contentitem hold viewmodel.

here of code project:

one of data templates xaml:

<usercontrol.resources>     <resourcedictionary>             <resourcedictionary.mergeddictionaries>         .         .         .             </resourcedictionary.mergeddictionaries>     </resourcedictionary>          <datatemplate datatype="{x:type viewmodels:installqueueviewmodel}">             <local:installqueueview datacontext="{binding path=datacontext.installqueuevm,                  relativesource={relativesource ancestortype={x:type usercontrol}}}" />         </datatemplate>     .     .     .         <datatemplate x:key="datatemplatetabcontrolcontent">             <contentcontrol content="{binding contentitem}"></contentcontrol>         </datatemplate> </usercontrol.resources>  <grid>     <tabcontrol itemssource="{binding activecontents}"                 selectedindex="{binding selectedtab, mode=twoway}"                 issynchronizedwithcurrentitem="true"                 itemcontainerstyle="{dynamicresource tabitemcontainerstylespacedmedium}"                 itemtemplate="{staticresource datatemplatetabcontrolheader}"                 contenttemplate="{staticresource datatemplatetabcontrolcontent}">     </tabcontrol> 

is there way prevent loading new instance of view every time? said, first time, it's entirely possible going wrong way - if should change how i'm doing something, please let me know.

one thing guess should mention i'm using mahapps metro feel application. i'm not sure if contributing @ lag i'm seeing.

i seeing lag when switch view contains datagrid. considering changing listview since data read-only, , hoping have give me improvement, root cause still unresolved.

any appreciated.

this huge problem me 1 project, , ended creating extended tabcontrol save contentpresenter of each tabitem when switching tabs, , reloading when go tab.

the original version of code here, or can find version of code in related question problem while back: wpf tabcontrol - preventing unload on tab change?

// extended tabcontrol saves displayed item don't performance hit of  // unloading , reloading visualtree when switching tabs  // obtained http://eric.burke.name/dotnetmania/2009/04/26/22.09.28 // , made modifications reuses tabitem's contentpresenter when doing drag/drop operations  [templatepart(name = "part_itemsholder", type = typeof(panel))] public class tabcontrolex : system.windows.controls.tabcontrol {     // holds items, marks current tab's item visible     private panel _itemsholder = null;      // temporaily holds deleted item in case drag/drop operation     private object _deletedobject = null;      public tabcontrolex()         : base()     {         // necessary initial databound selected item         this.itemcontainergenerator.statuschanged += itemcontainergenerator_statuschanged;     }      /// <summary>     /// if containers done, generate selected item     /// </summary>     /// <param name="sender"></param>     /// <param name="e"></param>     void itemcontainergenerator_statuschanged(object sender, eventargs e)     {         if (this.itemcontainergenerator.status == generatorstatus.containersgenerated)         {             this.itemcontainergenerator.statuschanged -= itemcontainergenerator_statuschanged;             updateselecteditem();         }     }      /// <summary>     /// itemsholder , generate children     /// </summary>     public override void onapplytemplate()     {         base.onapplytemplate();         _itemsholder = gettemplatechild("part_itemsholder") panel;         updateselecteditem();     }      /// <summary>     /// when items change remove generated panel children , add new ones necessary     /// </summary>     /// <param name="e"></param>     protected override void onitemschanged(notifycollectionchangedeventargs e)     {         base.onitemschanged(e);          if (_itemsholder == null)         {             return;         }          switch (e.action)         {             case notifycollectionchangedaction.reset:                 _itemsholder.children.clear();                  if (base.items.count > 0)                 {                     base.selecteditem = base.items[0];                     updateselecteditem();                 }                  break;              case notifycollectionchangedaction.add:             case notifycollectionchangedaction.remove:                  // search deleted items caused drag/drop operation                 if (e.newitems != null && _deletedobject != null)                 {                     foreach (var item in e.newitems)                     {                         if (_deletedobject == item)                         {                             // if new item same deleted 1 (i.e. drag/drop event)                             // cancel deletion , reuse contentpresenter doesn't have                              // redrawn. need link presenter new item though (using tag)                             contentpresenter cp = findchildcontentpresenter(_deletedobject);                             if (cp != null)                             {                                 int index = _itemsholder.children.indexof(cp);                                  (_itemsholder.children[index] contentpresenter).tag =                                     (item tabitem) ? item : (this.itemcontainergenerator.containerfromitem(item));                             }                             _deletedobject = null;                         }                     }                 }                  if (e.olditems != null)                 {                     foreach (var item in e.olditems)                     {                          _deletedobject = item;                          // want run @ later priority in case                         // drag/drop operation can reuse template                         this.dispatcher.begininvoke(dispatcherpriority.databind,                             new action(delegate()                         {                             if (_deletedobject != null)                             {                                 contentpresenter cp = findchildcontentpresenter(_deletedobject);                                 if (cp != null)                                 {                                     this._itemsholder.children.remove(cp);                                 }                             }                         }                         ));                     }                 }                  updateselecteditem();                 break;              case notifycollectionchangedaction.replace:                 throw new notimplementedexception("replace not implemented yet");         }     }      /// <summary>     /// update visible child in itemsholder     /// </summary>     /// <param name="e"></param>     protected override void onselectionchanged(selectionchangedeventargs e)     {         base.onselectionchanged(e);         updateselecteditem();     }      /// <summary>     /// generate contentpresenter selected item     /// </summary>     void updateselecteditem()     {         if (_itemsholder == null)         {             return;         }          // generate contentpresenter if necessary         tabitem item = getselectedtabitem();         if (item != null)         {             createchildcontentpresenter(item);         }          // show right child         foreach (contentpresenter child in _itemsholder.children)         {             child.visibility = ((child.tag tabitem).isselected) ? visibility.visible : visibility.collapsed;         }     }      /// <summary>     /// create child contentpresenter given item (could data or tabitem)     /// </summary>     /// <param name="item"></param>     /// <returns></returns>     contentpresenter createchildcontentpresenter(object item)     {         if (item == null)         {             return null;         }          contentpresenter cp = findchildcontentpresenter(item);          if (cp != null)         {             return cp;         }          // actual child added.  cp.tag reference tabitem         cp = new contentpresenter();         cp.content = (item tabitem) ? (item tabitem).content : item;         cp.contenttemplate = this.selectedcontenttemplate;         cp.contenttemplateselector = this.selectedcontenttemplateselector;         cp.contentstringformat = this.selectedcontentstringformat;         cp.visibility = visibility.collapsed;         cp.tag = (item tabitem) ? item : (this.itemcontainergenerator.containerfromitem(item));         _itemsholder.children.add(cp);         return cp;     }      /// <summary>     /// find cp given object.  data tabitem or piece of data     /// </summary>     /// <param name="data"></param>     /// <returns></returns>     contentpresenter findchildcontentpresenter(object data)     {         if (data tabitem)         {             data = (data tabitem).content;         }          if (data == null)         {             return null;         }          if (_itemsholder == null)         {             return null;         }          foreach (contentpresenter cp in _itemsholder.children)         {             if (cp.content == data)             {                 return cp;             }         }          return null;     }      /// <summary>     /// copied tabcontrol; wish protected in class instead of private     /// </summary>     /// <returns></returns>     protected tabitem getselectedtabitem()     {         object selecteditem = base.selecteditem;         if (selecteditem == null)         {             return null;         }          if (_deletedobject == selecteditem)         {           }          tabitem item = selecteditem tabitem;         if (item == null)         {             item = base.itemcontainergenerator.containerfromindex(base.selectedindex) tabitem;         }         return item;     } } 

Comments

Popular posts from this blog

java - Intellij Synchronizing output directories .. -

git - Initial Commit: "fatal: could not create leading directories of ..." -