WPF - reset ListBox scroll position when ItemsSource changes -
i have listbox itemssource collection bound property on viewmodel, of type ienumerable. when preoprty's reference changes, listbox updates expected, have problem in if have large collection of items , scroll bottom of listbox, , change reference collection containing, say, 1 item, listbox view blank , no scrollbar displayed. have scroll listbox mouse wheel, until 1 item comes view.
so, think i'm after, way of resetting scroll position of listbox top, whenever itemssource property changes, displayed no matter how large or small collection.
i'm unable reproduce problem (for me, listbox
scrolled last item in new collection when changing itemssource
). anyway, scroll listbox
top every time itemssource
changes can use code behind. first listen changes in itemssourceproperty
, scroll listbox
top once items has been generated
update
made attached behavior instead avoid code behind. can used this
<listbox ... behaviors:scrolltotopbehavior.scrolltotop="true"/>
scrolltotopbehavior
public static class scrolltotopbehavior { public static readonly dependencyproperty scrolltotopproperty = dependencyproperty.registerattached ( "scrolltotop", typeof(bool), typeof(scrolltotopbehavior), new uipropertymetadata(false, onscrolltotoppropertychanged) ); public static bool getscrolltotop(dependencyobject obj) { return (bool)obj.getvalue(scrolltotopproperty); } public static void setscrolltotop(dependencyobject obj, bool value) { obj.setvalue(scrolltotopproperty, value); } private static void onscrolltotoppropertychanged(dependencyobject dpo, dependencypropertychangedeventargs e) { itemscontrol itemscontrol = dpo itemscontrol; if (itemscontrol != null) { dependencypropertydescriptor dependencypropertydescriptor = dependencypropertydescriptor.fromproperty(itemscontrol.itemssourceproperty, typeof(itemscontrol)); if (dependencypropertydescriptor != null) { if ((bool)e.newvalue == true) { dependencypropertydescriptor.addvaluechanged(itemscontrol, itemssourcechanged); } else { dependencypropertydescriptor.removevaluechanged(itemscontrol, itemssourcechanged); } } } } static void itemssourcechanged(object sender, eventargs e) { itemscontrol itemscontrol = sender itemscontrol; eventhandler eventhandler = null; eventhandler = new eventhandler(delegate { if (itemscontrol.itemcontainergenerator.status == generatorstatus.containersgenerated) { scrollviewer scrollviewer = getvisualchild<scrollviewer>(itemscontrol) scrollviewer; scrollviewer.scrolltotop(); itemscontrol.itemcontainergenerator.statuschanged -= eventhandler; } }); itemscontrol.itemcontainergenerator.statuschanged += eventhandler; } }
and implementation of getvisualchild
private t getvisualchild<t>(dependencyobject parent) t : visual { t child = default(t); int numvisuals = visualtreehelper.getchildrencount(parent); (int = 0; < numvisuals; i++) { visual v = (visual)visualtreehelper.getchild(parent, i); child = v t; if (child == null) { child = getvisualchild<t>(v); } if (child != null) { break; } } return child; }
Comments
Post a Comment