c# - Sorting second level of TreeView and seeing changes... possible? -


this first post here, have been trying few techniques found in other questions can't seem working want... making changes existing application (.net 3.5 wpf , c#, , entity framework sqlserver2008). new both efdm , wpf. new version needs compatible existing databases previous version, without modification existing databases, quite reluctant changing datamodel , objects generated it.

anyway, here's question: have objects "staffincentive" , "staffincentivelines" edm, each staffincentive having 0 many staffincentiveline attached. display treeview, , need able dynamically add or remove staffincentiveline.

<treeview itemssource="{binding}" name="maintree">     <treeview.itemtemplate>         <hierarchicaldatatemplate itemssource="{binding staffincentiveline}">         <textbox text="{binding name}"/>         <button tag="{binding}" click="addline" content="add line" />             <hierarchicaldatatemplate.itemtemplate>                 <datatemplate >                         <textbox text="{binding lbound}"/>                         <textbox text="{binding percentage}"/>                         <button tag="{binding}" click="delline" content="remove"/>                 </datatemplate>             </hierarchicaldatatemplate.itemtemplate>         </hierarchicaldatatemplate>     </treeview.itemtemplate> </treeview> 

this works fine, staffincentivelines not sorted, need appear in order (ascending lbound). have looked solution , found converter

public object convert(object value, type targettype, object parameter, system.globalization.cultureinfo culture)         {return ((entitycollection<staffincentiveline>)value).orderby(o => o.lbound);} 

then realised when add or remove staffincentiveline using buttons on screen, changes not display. if understand corrently it's because incentivelines displayed through view provided sort converter, , view not refreshed when changes made collection. if understand correctly again, because entitycollection doesn't implement inotifypropertychanged. if refresh view using
collectionviewsource.getdefaultview(_incentives).refresh(); treeview gets refreshed , items collapsed quite confusing user...

so how can have both sorting , refreshing working without changing object classes staffincentive , staffincentiveline? should create class includes them , implement inotifypropertychanged?

thanks

i managed :)

i have created 2 classes staffincentivehelperobject , staffincentivelinehelperobject implement inotifypropertychanged. overlap existing classes , fire events when changes made through accessers. can there methods add/remove staffincentivelinehelperobject observablecollection in staffincentivehelperobject , , these methods add/remove original object edm... bit links changes made view database.

public class staffincentivehelperobject : inotifypropertychanged//     {         public delegate void collectionchangeddelegate();         public static collectionchangeddelegate collectionchanged;          public staffincentivehelperobject(staffincentive input)         {             this._staffincentive = input;         }           private staffincentive _staffincentive;         public staffincentive staffincentive         {             { return _staffincentive; }             set             {                 if (_staffincentive == value) return;                 _staffincentive = value;                 onpropertychanged("staffincentive");             }         }          public decimal? staffincentiveincrement         {                          {                  return _staffincentive.increment;              }             set             {                 if (_staffincentive.increment != value)                 {                     _staffincentive.increment = value;                     onpropertychanged("staffincentive");                 }             }         }          public string staffincentivename         {                         {                 return _staffincentive.name;             }             set             {                 if (_staffincentive.name != value)                 {                     _staffincentive.name = value;                     onpropertychanged("staffincentive");                 }             }         }          public byte? staffincentivetype         {                         {                 return _staffincentive.type;             }             set             {                 if(_staffincentive.type != value)                 {                     _staffincentive.type = value;                     onpropertychanged("staffincentive");                 }             }         }          private observablecollection<staffincentivelinehelperobject> _staffincentivelines = new observablecollection<staffincentivelinehelperobject>();         public observablecollection<staffincentivelinehelperobject> staffincentivelines         {             { return _staffincentivelines; }             set { _staffincentivelines = value; onpropertychanged("staffincentivelines"); }         }           public void addstaffincentiveline( staffincentiveline sil)         {             sil.staffincentive = this._staffincentive;             _staffincentive.staffincentiveline.add(sil);             staffincentivelines.add(new staffincentivelinehelperobject(sil, this));             //onpropertychanged("staffincentiveline");             if (collectionchanged != null)             {                 collectionchanged.invoke();             }          }          public void removestaffincentiveline(staffincentivelinehelperobject silho)         {             _staffincentive.staffincentiveline.remove(silho.staffincentiveline);             _staffincentivelines.remove(silho);             //onpropertychanged("staffincentiveline");             if (collectionchanged != null)             {                 collectionchanged.invoke();             }          }          #region inotifypropertychanged members          public event propertychangedeventhandler propertychanged;          private void onpropertychanged(string name)         {             var x = propertychanged;             if (x != null)                 x(this, new propertychangedeventargs(name));         }          #endregion     }      public class staffincentivelinehelperobject : inotifypropertychanged//, inotifyco     {         public staffincentivelinehelperobject(staffincentiveline input, staffincentivehelperobject parent)         {             this._staffincentiveline = input;             this.parent = parent;         }           public staffincentivehelperobject parent { get; set;}          private staffincentiveline _staffincentiveline;         public staffincentiveline staffincentiveline         {             { return _staffincentiveline; }             set             {                 if (_staffincentiveline == value) return;                 _staffincentiveline = value;                 onpropertychanged("staffincentiveline");             }         }          public decimal? staffincentivelinelbound         {                         {                 return _staffincentiveline.lbound;             }             set             {                 if (_staffincentiveline.lbound != value)                 {                     _staffincentiveline.lbound = value;                     onpropertychanged("staffincentiveline");                 }             }         }          public double? staffincentivelinepercentage         {                         {                 return _staffincentiveline.percentage;             }             set             {                 if (_staffincentiveline.percentage != value)                 {                     _staffincentiveline.percentage = value;                     onpropertychanged("staffincentiveline");                 }             }         }          #region inotifypropertychanged members          public event propertychangedeventhandler propertychanged;          private void onpropertychanged(string name)         {             var x = propertychanged;             if (x != null)                 x(this, new propertychangedeventargs(name));          }          #endregion     } 

the datacontext of xaml set observablecollection built existing objects of edm this

observablecollection<supportingobjects.staffincentivehelperobject> myicentives = new observablecollection<supportingobjects.staffincentivehelperobject>(); foreach (staffincentive si in db_incentives) {     staffincentivehelperobject siho = new staffincentivehelperobject(si);     myicentives.add(siho);     foreach (staffincentiveline sil in si.staffincentiveline)     {         siho.addstaffincentiveline(sil);     } } 

then xaml displays/updates using accessers.

<treeview itemssource="{binding}" name="maintree"> <treeview.itemtemplate>     <hierarchicaldatatemplate itemssource="{binding staffincentivelines, converter={staticresource incentivelinehelperobjectsort}, converterparameter=staffincentivelinelbound}">         <stackpanel orientation="horizontal" >             <textbox text="{binding staffincentivename}" width="120" />             <button tag="{binding}" click="addline" content="add line" />         </stackpanel>         <hierarchicaldatatemplate.itemtemplate>             <datatemplate >                 <stackpanel orientation="horizontal"  margin="150,0,0,0">                     <textbox text="{binding staffincentivelinelbound, stringformat='{}{0:c}'}" width="120" />                     <textbox text="{binding staffincentivelinepercentage}" width="120" />                 <button tag="{binding}" click="delline" content="remove"/>                 </stackpanel>             </datatemplate>         </hierarchicaldatatemplate.itemtemplate>     </hierarchicaldatatemplate> </treeview.itemtemplate> 

the sorting done @ first load , not dynamically while adding lines, fine me. here's sort converter (i copied question on site)

public class incentivelinehelperobjectsort : ivalueconverter     {         public object convert(object value, type targettype, object parameter, system.globalization.cultureinfo culture)         {             system.collections.objectmodel.observablecollection<staffincentivelinehelperobject> collection = value system.collections.objectmodel.observablecollection<staffincentivelinehelperobject>;             listcollectionview view = new listcollectionview(collection);             system.componentmodel.sortdescription sort = new system.componentmodel.sortdescription(parameter.tostring(), system.componentmodel.listsortdirection.ascending);             view.sortdescriptions.add(sort);              return view;         }          public object convertback(object value, type targettype, object parameter, system.globalization.cultureinfo culture)         {             return null;         }     } 

here's methods add or remove staffincentivelines when buttons pressed.

private void addline(object sender, routedeventargs e)         {             var incentive = ((sender button).tag staffincentivehelperobject);             incentive.addstaffincentiveline(new staffincentiveline());             treeviewitem thistreeviewitem = maintree.itemcontainergenerator.containerfromitem(incentive) treeviewitem;             thistreeviewitem.isexpanded = true;         }          private void delline(object sender, routedeventargs e)         {             var line = ((sender button).tag staffincentivelinehelperobject);             staffincentivehelperobject thisincentive = line.parent;              thisincentive.removestaffincentiveline(line);             treeviewitem thistreeviewitem = maintree.itemcontainergenerator.containerfromitem(thisincentive) treeviewitem;             if (thisincentive.staffincentivelines.count == 0)             {                  thistreeviewitem.isexpanded = false;             }         } 

if else has better way, or means improve this, i'd happy hear :)


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -