Nell'articolo mancano però i metodi per gestire il controllo ListBox, vi aggiungo qui sotto i metodi da aggiungere per poter agilmente salvare lo stato di questo controllo :
Nel metodo RestoreState() potete aggiungere anche il ripristino dell'elemento selezionato se vi interessa (basta aggiungere : listbox.SelectedIndex = data.selectedIndex;)
Un'altra cosa, ho trovato un piccolo Bug nell'articolo MSDN sopra indicato, nel metodo PreserveState del controllo ScrollViewer viene salvato due volte il VerticalOffset :
1: /// <summary>
2: /// Saves the scroll offset of a ListBox to the state dictionary.
3: /// </summary>
4: /// <param name="state">The calling page's state dictionary.</param>
5: /// <param name="scrollViewer">The ListBox to be preserved.</param>
6: public static void PreserveState(IDictionary<string, object> state, ListBox listbox)
7: {
8:
9: ScrollViewer viewer = ((VisualTreeHelper.GetChild(listbox, 0) as FrameworkElement).FindName("ScrollViewer") as ScrollViewer);
10: if (viewer != null) {
11: state[listbox.Name + "_HorizontalOffset"] = viewer.HorizontalOffset;
12: state[listbox.Name + "_VerticalOffset"] = viewer.VerticalOffset;
13: }
14:
15: state[listbox.Name + "_selectedIndex"] = listbox.SelectedIndex;
16: }
17:
18: public class datListBox {
19: public double offsetX=0;
20: public double offsetY=0;
21: public int selectedIndex=-1;
22: }
23:
24: /// <summary>
25: /// Retrieves the saved scroll offset from the state dictionary and creates a delegate to
26: /// restore the scroll position on the page's first render.
27: /// </summary>
28: /// <param name="state">The calling page's state dictionary</param>
29: /// <param name="scrollViewer">The ListBox to be restored</param>
30: public static datListBox RestoreState(IDictionary<string, object> state, ListBox listbox)
31: {
32: datListBox data = new datListBox();
33: data.offsetX = TryGetValue<double>(state, listbox.Name + "_HorizontalOffset", 0);
34: data.offsetY = TryGetValue<double>(state, listbox.Name + "_VerticalOffset", 0);
35: data.selectedIndex = TryGetValue<int>(state, listbox.Name + "_selectedIndex", -1);
36:
37: ScheduleOnNextRender(delegate { RestoreState(listbox,data); });
38: return data;
39: }
40:
41: private static void RestoreState(ListBox listbox,datListBox data)
42: {
43: if (listbox == null || data == null ) return;
44: ScrollViewer viewer = ((VisualTreeHelper.GetChild(listbox, 0) as FrameworkElement).FindName("ScrollViewer") as ScrollViewer);
45: if (viewer != null)
46: {
47: viewer.ScrollToHorizontalOffset(data.offsetX);
48: viewer.ScrollToVerticalOffset(data.offsetY);
49: }
50: }
Nel metodo RestoreState() potete aggiungere anche il ripristino dell'elemento selezionato se vi interessa (basta aggiungere : listbox.SelectedIndex = data.selectedIndex;)
Un'altra cosa, ho trovato un piccolo Bug nell'articolo MSDN sopra indicato, nel metodo PreserveState del controllo ScrollViewer viene salvato due volte il VerticalOffset :
1: public static void PreserveState(IDictionary<string, object> state, ScrollViewer scrollViewer)
2: {
3: state[scrollViewer.Name + "_HorizontalOffset"] = scrollViewer.VerticalOffset;
4: state[scrollViewer.Name + "_VerticalOffset"] = scrollViewer.VerticalOffset;
5: }
Modificatelo così :
1: public static void PreserveState(IDictionary<string, object> state, ScrollViewer scrollViewer)
2: {
3: state[scrollViewer.Name + "_HorizontalOffset"] = scrollViewer.HorizontalOffset;
4: state[scrollViewer.Name + "_VerticalOffset"] = scrollViewer.VerticalOffset;
5: }