wpf - Strange out of order behavior for TreeView and compound data -


the follow code loads hierarchical collection of compoundobjects of strings. unfortunately inserts strings @ top of tree instead of @ bottom(which behavior i've seen.

i've tried change order of enumerators, notifiers, etc , produce same results. i've pre-load list looks normal(using same code in thread).

any ideas whats going on?

compoundobject.cs

using system; using system.collections.generic; using system.collections.objectmodel; using system.collections.specialized; using system.linq; using system.text;  namespace complextreeviewlazyloadingtest {     public class compoundobject : ienumerable<object>, inotifycollectionchanged     {         public string name { get; set; }         public observablecollection<compoundobject> objects { get; private set; }         public observablecollection<string> items { get; private set; }          void onchanged(object sender, notifycollectionchangedeventargs e)          {              if (collectionchanged != null)              app.current.dispatcher.invoke((action<object, notifycollectionchangedeventargs>)((senderr, ee) => {                 collectionchanged(senderr, ee);              }), sender, e);         }          public compoundobject(string name)          {              name = name;              items = new observablecollection<string>();             objects = new observablecollection<compoundobject>();              items.collectionchanged += new notifycollectionchangedeventhandler(onchanged);             objects.collectionchanged += new notifycollectionchangedeventhandler(onchanged);         }           public ienumerator<object> getenumerator()         {             if (objects != null) foreach(var in objects) yield return a;             if (items != null) foreach (var in items) yield return a;                      yield break;         }          system.collections.ienumerator system.collections.ienumerable.getenumerator() { return getenumerator(); }            public event notifycollectionchangedeventhandler collectionchanged;      }    } 

mainwindow.xaml.cs

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.threading;  namespace complextreeviewlazyloadingtest {       public partial class mainwindow : window     {          compoundobject c = new compoundobject("root");         public mainwindow()         {             initializecomponent();              treeview.datacontext = c;             treeview.itemssource = c;              threadpool.queueuserworkitem(new waitcallback(update));          }           void update(object data)         {               (int = 0; < 10; i++)             {                 application.current.dispatcher.invoke((action<compoundobject>)((cc) => {                     c.objects.add(cc);                 }), new compoundobject("object " + i));                  (int j = 0; j < 5; j++)                 {                     thread.sleep(100);                     application.current.dispatcher.invoke((action<compoundobject>)((cc) =>                     {                         c.objects[i].objects.add(cc);                     }), new compoundobject("subobject " + j));                  }              }              (int = 0; < 8; i++)             {                 thread.sleep(250);                 application.current.dispatcher.invoke((action<string>)((ii) =>                 {                     c.items.add("item " + ii);                 }), i.tostring());             }            }      } // mainwindow        public class dts : datatemplateselector     {         public override datatemplate selecttemplate(object item, dependencyobject container)         {             frameworkelement element = container frameworkelement;              if (element != null && item != null)             {                  if (item compoundobject)                 {                     return element.findresource("compoundtemplate") datatemplate;                 }                  if (item int)                 {                     return element.findresource("defaulttemplate") datatemplate;                 }             }                return null;         }     }   } 

mainwindow.xaml

<window x:class="complextreeviewlazyloadingtest.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:complextreeviewlazyloadingtest;assembly="         title="mainwindow" height="350" width="525">     <window.resources>          <local:dts x:key="dts"/>          <hierarchicaldatatemplate x:key="compoundtemplate" itemssource="{binding path=.}">             <textblock text="{binding name}" />         </hierarchicaldatatemplate>          <hierarchicaldatatemplate x:key="defaulttemplate" itemssource="{binding path=.}">             <textblock text="{binding path=.}" background="aqua" />         </hierarchicaldatatemplate>      </window.resources>           <grid>           <treeview name="treeview" itemtemplateselector="{staticresource dts}"/>      </grid> </window> 

because you're combining 2 collections , subscribing collectionchanged directly, change notifications sub-lists instead of 'combined' list. means you'll notification 'string added @ 0' when want added @ end of list. in order make work, you'll need subscribe collectionchanged each sub-collection , implement own collectionchanged callback (to add first collection's count indices reported when adding/removing strings.)


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -