1: public static class AppBarExtensions
2: {
3: [Flags]
4: public enum AppBarDisplayFlags
5: {
6: None = 0,
7: Bottom = 1,
8: Top = 2,
9: BottomAndTop = 3,
10: }
11:
12: public static readonly DependencyProperty AppBarDisplayOnListSelectionProperty =
13: DependencyProperty.RegisterAttached(
14: "AppBarDisplayOnListSelection",
15: typeof(AppBarDisplayFlags),
16: typeof(Selector),
17: new PropertyMetadata(AppBarDisplayFlags.None, OnAppBarDisplayOnListSelectionChanged));
18:
19: public static void SetAppBarDisplayOnListSelection(Selector element, AppBarDisplayFlags value)
20: {
21: element.SetValue(AppBarDisplayOnListSelectionProperty, value);
22: }
23:
24: public static AppBarDisplayFlags GetAppBarDisplayOnListSelection(Selector element)
25: {
26: return (AppBarDisplayFlags)element.GetValue(AppBarDisplayOnListSelectionProperty);
27: }
28:
29: private static void OnAppBarDisplayOnListSelectionChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
30: {
31: // Don't hook up the event listeners when running in the designer
32: if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) return;
33:
34: // Identify the selector to which this property has been applied (if none, then do nothing)
35: var selector = dependencyObject as Selector;
36: if (selector == null) return;
37:
38: var selectedFlags = (AppBarDisplayFlags)dependencyPropertyChangedEventArgs.NewValue;
39: HookEvents(selector, selectedFlags);
40: }
41:
42: private static void HookEvents(Selector selector, AppBarDisplayFlags flags)
43: {
44: if (selector == null) throw new ArgumentNullException("selector");
45:
46: // Clear any "active" event handlers
47: UnhookEvents(selector);
48:
49: if (flags != AppBarDisplayFlags.None)
50: {
51: selector.Unloaded += HandleUnloaded;
52: selector.SelectionChanged += HandleSelectionChanged;
53: }
54: }
55:
56: private static void UnhookEvents(Selector selector)
57: {
58: if (selector == null) throw new ArgumentNullException("selector");
59:
60: selector.Unloaded -= HandleUnloaded;
61: selector.SelectionChanged -= HandleSelectionChanged;
62: }
63:
64: private static void HandleUnloaded(Object sender, RoutedEventArgs e)
65: {
66: UnhookEvents((Selector)sender);
67: }
68:
69: private static void HandleSelectionChanged(Object sender, SelectionChangedEventArgs e)
70: {
71: var selector = sender as Selector;
72: if (selector == null) return;
73:
74: // Traverse the selector's parents to find the firet "page" element
75: var containingPage = selector.GetVisualAncestors().OfType<Page>().FirstOrDefault();
76: if (containingPage == null) return;
77:
78: var currentFlags = GetAppBarDisplayOnListSelection(selector);
79: var showBottomAppBar = (currentFlags & AppBarDisplayFlags.Bottom) == AppBarDisplayFlags.Bottom;
80: var showTopAppBar = (currentFlags & AppBarDisplayFlags.Top) == AppBarDisplayFlags.Top;
81:
82: if (selector.SelectedItem != null)
83: {
84: // An item has been selected - show the relevant app bars
85: if (showBottomAppBar) ShowAppBar(containingPage.BottomAppBar);
86: if (showTopAppBar) ShowAppBar(containingPage.TopAppBar);
87: }
88: else
89: {
90: // Nothing has been selected - hide the relevant app bars
91: if (showBottomAppBar) HideAppBar(containingPage.BottomAppBar);
92: if (showTopAppBar) HideAppBar(containingPage.TopAppBar);
93: }
94: }
95:
96: private static void ShowAppBar(AppBar appBar)
97: {
98: if (appBar == null) return;
99:
100: appBar.IsSticky = true;
101: appBar.IsOpen = true;
102: }
103:
104: private static void HideAppBar(AppBar appBar)
105: {
106: if (appBar == null) return;
107:
108: appBar.IsOpen = false;
109: appBar.IsSticky = false;
110: }
111:
112: /// <summary>
113: /// Gets the ancestors of the element, up to the root.
114: /// </summary>
115: /// <param name="node">The element to start from.</param>
116: /// <returns>An enumerator of the ancestors.</returns>
117: public static IEnumerable<FrameworkElement> GetVisualAncestors(this FrameworkElement node)
118: {
119: var parent = node.GetVisualParent();
120: while (parent != null)
121: {
122: yield return parent;
123: parent = parent.GetVisualParent();
124: }
125: }
126:
127: /// <summary>
128: /// Gets the visual parent of the element.
129: /// </summary>
130: /// <param name="node">The element to check.</param>
131: /// <returns>The visual parent.</returns>
132: public static FrameworkElement GetVisualParent(this FrameworkElement node)
133: {
134: return VisualTreeHelper.GetParent(node) as FrameworkElement;
135: }
136: }