wpf - Massive performance issue with nested ItemsControl -


i use nested itemscontrol display hierarchical data. problem terribly slow little data. blocking ui-thread until data loaded. doing wrong here?

code generate demo-data , bind itemscontrol:

private void setupdemodata()     {         observablecollection<folder> demodata = new observablecollection<folder>();          const int numberoffolders = 1;         const int numberoffiles = 1;         const int numberoflines = 300;          random randcontentlength = new random();           for( int indexfolders = 0; indexfolders <= numberoffolders; indexfolders++ )         {             folder newfolder = new folder {foldername = string.format( "demofolder {0}", indexfolders )};              for( int indexfiles = 0; indexfiles <= numberoffiles; indexfiles++ )             {                 file newfile = new file {filename = string.format( "demofile {0} -> {1}", indexfolders, indexfiles )};                   for( int indexlines = 0; indexlines <= numberoflines; indexlines++ )                 {                     newfile.contentlines.add( new filecontentline                         {                             linecontent = getrandomstring( randcontentlength.next( 80 ) ),                             linenumber = indexlines                         } );                 }                 newfolder.files.add( newfile );             }             demodata.add( newfolder );         }          this.icfolders.itemssource = demodata;     }      private static readonly random random = new random();     private static string getrandomstring(int length )     {         length = math.max( length, 3 );         byte[] bytes = new byte[length];         random.nextbytes( bytes );         return convert.tobase64string( bytes ).substring( 0, length );     } 

the models:

public class folder {     public list<file> files { get; set; }     public string foldername { get; set; }     public folder(){ this.files = new list<file>();} }  public class file {     public list<filecontentline> contentlines { get; set; }     public string filename { get; set; }     public file() { this.contentlines = new list<filecontentline>(); } }  public class filecontentline {     public int linenumber { get; set; }     public string linecontent { get; set; } } 

and xaml:

<grid>     <scrollviewer verticalscrollbarvisibility="auto">         <grid>              <grid>                 <itemscontrol grid.row="0" x:name="icfolders" horizontalcontentalignment="stretch" verticalcontentalignment="stretch" >                      <!-- folder -->                     <itemscontrol.itemtemplate>                         <datatemplate datatype="{x:type local:folder}">                             <grid margin="0">                                 <grid.rowdefinitions>                                     <rowdefinition height="auto"/>                                     <rowdefinition height="auto"/>                                     <rowdefinition height="*"/>                                 </grid.rowdefinitions>                                 <border grid.row="0" borderthickness="0,1,0,1" borderbrush="#c5c5c5">                                     <grid grid.row="0" style="{staticresource stylegridgradient}">                                         <grid>                                             <grid.columndefinitions>                                                 <columndefinition width="auto" />                                                 <columndefinition width="*" />                                                 <columndefinition width="auto" />                                             </grid.columndefinitions>                                             <label grid.column="0" style="{staticresource stylelabelbold}" content="{binding foldername}" />                                             <label grid.column="2" style="{staticresource stylelabelbold}" content="{binding files.count}" />                                         </grid>                                     </grid>                                 </border>                                 <border grid.row="1" borderthickness="0,1,0,1" borderbrush="#c5c5c5">                                     <grid style="{staticresource stylegridgradient}">                                        <label foreground="#666666"                                         margin="5,0,0,0"                                         horizontalalignment="stretch"                                         content="{binding foldername}"  />                                     </grid>                                 </border>                                  <!--files -->                                 <itemscontrol grid.row="2" itemssource="{binding files}" >                                     <itemscontrol.itemtemplate>                                         <datatemplate datatype="{x:type local:file}">                                             <grid margin="0">                                                 <grid.rowdefinitions>                                                     <rowdefinition height="auto" />                                                     <rowdefinition height="*" />                                                 </grid.rowdefinitions>                                                 <border grid.row="0" borderthickness="0,1,0,1" borderbrush="#c5c5c5">                                                     <grid style="{staticresource stylegridgradient}">                                                         <grid.columndefinitions>                                                             <columndefinition width="*"/>                                                             <columndefinition width="auto"/>                                                         </grid.columndefinitions>                                                          <label grid.column="0"                                                            foreground="#666666"                                                            margin="5,0,0,0"                                                            verticalcontentalignment="center"                                                            verticalalignment="center"                                                            content="{binding filename}" />                                                          <button grid.column="1" margin="5" maxheight="25" content="open file"/>                                                      </grid>                                                 </border>                                                  <!-- lines -->                                                 <itemscontrol grid.row="1" itemssource="{binding contentlines}" background="white">                                                     <itemscontrol.itemtemplate>                                                         <datatemplate datatype="{x:type local:filecontentline}">                                                             <grid margin="0" height="20">                                                                 <grid.columndefinitions>                                                                     <columndefinition width="35" />                                                                     <columndefinition width="20" />                                                                     <columndefinition width="*" />                                                                 </grid.columndefinitions>                                                                  <border grid.column="0" borderthickness="0,0,1,0" borderbrush="#c5c5c5">                                                                     <togglebutton>                                                                         <label content="{binding linenumber}" />                                                                     </togglebutton>                                                                 </border>                                                                  <border grid.column="2" borderthickness="0,0,1,0" borderbrush="#c5c5c5">                                                                     <border  grid.column="2" borderthickness="0,1,0,1" borderbrush="red">                                                                         <label height="20" content="+" horizontalalignment="center" />                                                                     </border>                                                                 </border>                                                                  <border grid.column="3" borderthickness="0,1,0,1" borderbrush="gray">                                                                     <textbox height="20" isreadonly="true"                                                                              verticalalignment="center"                                                                              verticalcontentalignment="center"                                                                              text="{binding linecontent}" />                                                                 </border>                                                             </grid>                                                         </datatemplate>                                                     </itemscontrol.itemtemplate>                                                 </itemscontrol>                                              </grid>                                         </datatemplate>                                     </itemscontrol.itemtemplate>                                 </itemscontrol>                              </grid>                         </datatemplate>                     </itemscontrol.itemtemplate>                 </itemscontrol>             </grid>         </grid>     </scrollviewer> </grid> 

add following property itemscontrols (root , nested ones):

<itemscontrol.itemspanel>   <itemspaneltemplate>      <virtualizingstackpanel/>   </itemspaneltemplate> </itemscontrol.itemspanel> 

Comments