Resolves an issue that does not reset scrollbar when a listbox ItemsSource changes in a WPF program
When we change the ItemsSource of the ListBox, we find the problem: when the data source changes, the content in the control changes, but the scrollbar does not reset.
As an example:
- Binds a listbox to 100 strings: Listbox.itemssource = Enumerable.range (0, 100). Select (i = "# #" + i);.
- Drag the scroll bar of the listbox to the end so that it can see the last "# # 99" and not see the first "# 0".
- Binds a listbox to another 100 strings: Listbox.itemssource = Enumerable.range (0, 100). Select (i = ">>" + i);. At this point we will find: Although the data content will change, but the scroll bar is still at the end, you can see the last ">> 99", do not see the first ">> 0".
In most cases, this is not the result we expect. How to solve this problem, StackOverflow article reset scrollbar on ItemsSource The change gives a solution: Find the ScrollViewer of the ListBox, Responds to the Sourceupdated event in the ListBox, scrolling the scroll bar to the top.
ListBox. sourceupdated + = (_1, _2) = Scrollview.scrolltotop ();
There is no problem with this approach in itself, but since ScrollViewer is part of the visual tree, getting it from the listbox is not easy (the template may be modified). I later from WordPress article listbox–automatically scroll currentitem into A scenario was found on view that responds to the Items.currentchanged event in the ListBox and scrolls to the top through the function scrollIntoView implementation.
ListBox. Items.currentchanged + = (_1, _2) = ListBox. scrollIntoView (ListBox. Items[0]);
The original purpose of this article is to implement the automatic scrolling of the listbox to CurrentItem, which can also be used to solve this problem. The original text also implements an additional attribute, which makes it very convenient to use it directly in XAML.
<listbox local:listboxextenders.autoscrolltocurrentitem= "True"/>
Because of the well-known reasons, WordPress This does not exist on the site can only be accessed from Mars, no Mars dedicated friends can find the principal to borrow, or directly refer to my code below (slightly modified point, seemingly there is no bug).
1 /// <summary> ///This class contains a few useful extenders for the ListBox/// </summary> Public classListboxextenders:dependencyobject {#regionProperties Public Static ReadOnlyDependencyProperty Autoscrolltocurrentitemproperty = dependencyproperty.registerattached ("Autoscrolltocurrentitem", typeof(BOOL),typeof(Listboxextenders),NewUIPropertyMetadata (default(BOOL) , onautoscrolltocurrentitemchanged)); /// <summary> ///Returns The value of the Autoscrolltocurrentitemproperty/// </summary> /// <param name= "obj" >The dependency-object whichs value should be returned</param> /// <returns>The value of the given property</returns> Public Static BOOLgetautoscrolltocurrentitem (DependencyObject obj) {return(BOOL) obj. GetValue (Autoscrolltocurrentitemproperty); } /// <summary> ///sets the value of the Autoscrolltocurrentitemproperty/// </summary> /// <param name= "obj" >The dependency-object whichs value should be set</param> /// <param name= "value" >The value which should is assigned to the Autoscrolltocurrentitemproperty</param> Public Static voidSetautoscrolltocurrentitem (DependencyObject obj,BOOLvalue) {obj. SetValue (autoscrolltocurrentitemproperty, value); } #endregion #regionEvents/// <summary> ///This method is called when the Autoscrolltocurrentitem///Property was changed/// </summary> /// <param name= "Sender" >The sender (the ListBox)</param> /// <param name= "E" >Some Additional Information</param> Public Static voidonautoscrolltocurrentitemchanged (DependencyObject sender, DependencyPropertyChangedEventArgs e) { /c2>varListBox = Sender asListBox; if(ListBox = =NULL) || (ListBox.Items = =NULL)) return; varEnable = (BOOL) E.newvalue; varAutoscrolltocurrentitemworker =NewEventHandler (_1, _2) =Onautoscrolltocurrentitem (ListBox, listBox.Items.CurrentPosition)); if(enable) listBox.Items.CurrentChanged+=Autoscrolltocurrentitemworker; ElselistBox.Items.CurrentChanged-=Autoscrolltocurrentitemworker; } /// <summary> ///This method is called when the ListBox should///be scrolled to the given index/// </summary> /// <param name= "ListBox" >The ListBox which should be scrolled</param> /// <param name= "index" >The index of the item to which it should is scrolled</param> Public Static voidOnautoscrolltocurrentitem (ListBox ListBox,intindex) { if(ListBox! =NULL&& ListBox.Items! =NULL&& listBox.Items.Count > Index && index >=0) Listbox.scrollintoview (Listbox.items[index]); } #endregion the
View Code
Resolves an issue that does not reset scrollbar when a listbox ItemsSource changes in a WPF program