wpf - Listbox using a data template and dynamic data loading based on selection Enumeration Error -
to can or show me better way. have tried observable collection, list based on custom class, global/non-global collections, using listbox's itemssource, synclocking, , emptying , manually entering in items.
it tends work fine, every once in while error "collection modified; enumeration operation may not execute." seems occur @ system.collections.arraylist.arraylistenumeratorsimple.movenext()
i have tried few different things on past couple of weeks , able avoid sometimes, can reproduce in different area.
essentially, have 3 listboxes parent, current, children. these have captioned images in them. when image selected images in parent, current, , children empty , reload based on selected image.
i've written in vb, can convert c# if help. code has been changed many times , latest 1 has lot of commented code in it. or suggestions appreciated. simplify it, work, or performance enhancements great.
imagine code in triplicate. code identical exception of names.
<page.resources> <collectionviewsource source="{binding source={x:static application.current}, path=currentlist}" x:key="currentlist" /> </page.resources> <scrollviewer grid.row="2" verticalscrollbarvisibility="disabled" panningmode="verticalonly" flowdirection="righttoleft" horizontalscrollbarvisibility="auto" > <listbox name="currentlistbox" verticalalignment ="stretch" margin=" 8" background="transparent" height="auto" borderthickness="0" horizontalcontentalignment="center" flowdirection="lefttoright" horizontalalignment="center" itemssource="{binding currentlist}"> <listbox.resources> <style targettype="{x:type listboxitem}"> <eventsetter event="listboxitem.selected" handler="currentlistboxitem_selected" handledeventstoo="false"/> </style> </listbox.resources> <listbox.itemspanel> <itemspaneltemplate> <wrappanel isitemshost="true" /> </itemspaneltemplate> </listbox.itemspanel> <listbox.itemtemplate> <datatemplate> <border borderbrush="#ff0000ac" style="{staticresource resourcekey=thumbnailborder}"> <!--<viewbox maxwidth ="100" >--> <stackpanel> <grid> <border name="itemborder" style="{staticresource resourcekey=thumbnailinnerborder}"/> <image name="personimage" maxheight ="200" maxwidth ="200" source="{binding profileimagepath}" horizontalalignment="center" > <image.opacitymask> <visualbrush visual="{binding elementname=itemborder}"/> </image.opacitymask> </image> </grid> <viewbox maxwidth ="190" margin="5,0,5,0" maxheight="15"> <textblock name="person" text="{binding profilename}" tag="{binding userid}" horizontalalignment="center" /> </viewbox> </stackpanel> <!--</viewbox>--> </border> </datatemplate> </listbox.itemtemplate> </listbox> </scrollviewer>
the collection stored in global variable , populated using sqlce command.
public shared currentpeoplelist new collectionviewsource public shared current_people_list new observablecollection(of currents)() public shared property currentlist() observablecollection(of currents) return current_people_list end set(byval value observablecollection(of currents)) current_people_list = value end set end property
the custom class of currents:
public class currents implements inotifypropertychanged private profilenamevalue string private useridvalue integer private profileimagepathvalue string public event propertychanged propertychangedeventhandler implements inotifypropertychanged.propertychanged
#region "properties getters , setters" public property profilename() string return me.profilenamevalue end set(byval value string) me.profilenamevalue = value onpropertychanged("profilename") end set end property
public property userid() integer return me.useridvalue end set(byval value integer) if value < 0 throw new argumentexception("user id must greater 0 ") end if me.useridvalue = value onpropertychanged("userid") end set end property public property profileimagepath() string return me.profileimagepathvalue end set(byval value string) me.profileimagepathvalue = relativeprogrampath() & "media\pictures\" & value onpropertychanged("profileimagepath") end set end property #end region public sub new(byval userid integer, byval profilename string, byval profileimagepath string) me.profilenamevalue = profilename me.useridvalue = userid me.profileimagepathvalue = if(profileimagepath "pack://*", profileimagepath, relativeprogrampath() & "media\pictures\" & profileimagepath) end sub protected sub onpropertychanged(byval name string) raiseevent propertychanged(me, new propertychangedeventargs(name)) end sub end class
finally, way these populated using common function
private sub reload(byval currentid integer) try try parentlist = nothing currentlist = nothing childrenlist = nothing catch end try try me.parentlistbox.itemssource = nothing me.currentlistbox.itemssource = nothing me.childlistbox.itemssource = nothing catch end try try currentpersonid = currentid 'load images based on people. dim ch = load_children_people(currentid) dim c = load_current_people(currentid) dim p = load_parent_people(currentid) parentlist = if(p.count > 0, p, nothing) currentlist = if(c.count > 0, c, nothing) childrenlist = if(ch.count > 0, ch, nothing) catch end try try if parentlist isnot nothing _ me.parentlistbox.itemssource = collectionviewsource.getdefaultview(parentlist) if currentlist isnot nothing _ me.currentlistbox.itemssource = collectionviewsource.getdefaultview(currentlist) if childrenlist isnot nothing _ me.childlistbox.itemssource = collectionviewsource.getdefaultview(childrenlist) catch end try catch end try 'for reason not work without pause. not sure why. 'fixme remove pause delay when able. 'thread.sleep(200) end sub
i used lot of try-catch's attempt catch error, have been unsuccessful far. suspicion error occurs during ui thread cannot seem pin down. mentioned earlier. assistance great.
Comments
Post a Comment