From a2057222e03c019f68ab7e486999016d73c7d7fd Mon Sep 17 00:00:00 2001 From: Shane Weaver Date: Thu, 27 May 2021 16:00:32 -0700 Subject: [PATCH 1/4] Added ElementExtensions --- .../Extensions/ElementExtensions.cs | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs diff --git a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs new file mode 100644 index 0000000..fbdd39d --- /dev/null +++ b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs @@ -0,0 +1,115 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using CommunityToolkit.Authentication; +using Windows.UI.Xaml; + +namespace CommunityToolkit.Graph.Uwp +{ + /// + /// Extensions on FrameworkElement for responding to authentication changes from XAML. + /// + public class ElementExtensions : DependencyObject + { + /// + /// Sets a value indicating whether an element should update its visibility based on provider state changes. + /// + /// The target element. + /// A nullable bool value. + public static void SetIsVisibleWhenSignedIn(FrameworkElement element, bool? value) + { + element.SetValue(_isVisibleWhenSignedInProperty, value); + } + + /// + /// Gets a value indicating whether an element should update its visibility based on provider state changes. + /// + /// The target element. + /// A nullable bool value. + public static bool? GetIsVisibleWhenSignedIn(FrameworkElement element) + { + return (bool?)element.GetValue(_isVisibleWhenSignedInProperty); + } + + private static readonly IList _listeningElements = new List(); + + private static readonly DependencyProperty _isVisibleWhenSignedInProperty = + DependencyProperty.RegisterAttached("IsVisibleWhenSignedIn", typeof(bool?), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenSignedInPropertyChanged)); + + private static void OnIsVisibleWhenSignedInPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is FrameworkElement element) + { + if (e.NewValue == null) + { + DeregisterElement(element); + } + else + { + RegisterElement(element); + } + + var providerState = ProviderManager.Instance.GlobalProvider?.State; + UpdateElementVisibility(element, providerState); + } + } + + private static void OnElementUnloaded(object sender, RoutedEventArgs e) + { + if (sender is FrameworkElement element) + { + DeregisterElement(element); + } + } + + private static void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e) + { + var provider = ProviderManager.Instance.GlobalProvider; + var providerState = provider?.State; + + foreach (var element in _listeningElements) + { + UpdateElementVisibility(element, providerState); + } + } + + private static void RegisterElement(FrameworkElement element) + { + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + element.Unloaded += OnElementUnloaded; + _listeningElements.Add(element); + } + + private static void DeregisterElement(FrameworkElement element) + { + ProviderManager.Instance.ProviderUpdated -= OnProviderUpdated; + element.Unloaded -= OnElementUnloaded; + _listeningElements.Remove(element); + } + + private static void UpdateElementVisibility(FrameworkElement element, ProviderState? providerState) + { + var isVisibleWhenSignedIn = GetIsVisibleWhenSignedIn(element); + + switch (isVisibleWhenSignedIn) + { + case true: + // When signed in, show the element. + element.Visibility = providerState == ProviderState.SignedIn ? Visibility.Visible : Visibility.Collapsed; + break; + + case false: + // When signed in, hide the element. + element.Visibility = providerState == ProviderState.SignedIn ? Visibility.Collapsed : Visibility.Visible; + break; + + default: + // Show the default visibility state. + element.Visibility = default; + break; + } + } + } +} From f782bea1e1ce439a64663e88650e6e9dd920b430 Mon Sep 17 00:00:00 2001 From: Shane Weaver Date: Tue, 1 Jun 2021 11:23:52 -0700 Subject: [PATCH 2/4] Bugfix --- .../Extensions/ElementExtensions.cs | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs index fbdd39d..7426489 100644 --- a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs +++ b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs @@ -13,6 +13,18 @@ namespace CommunityToolkit.Graph.Uwp /// public class ElementExtensions : DependencyObject { + private static readonly IList _listeningElements = new List(); + + private static readonly DependencyProperty _isVisibleWhenSignedInProperty = + DependencyProperty.RegisterAttached("IsVisibleWhenSignedIn", typeof(bool?), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenSignedInPropertyChanged)); + + static ElementExtensions() + { + _listeningElements = new List(); + + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + } + /// /// Sets a value indicating whether an element should update its visibility based on provider state changes. /// @@ -33,11 +45,6 @@ public static void SetIsVisibleWhenSignedIn(FrameworkElement element, bool? valu return (bool?)element.GetValue(_isVisibleWhenSignedInProperty); } - private static readonly IList _listeningElements = new List(); - - private static readonly DependencyProperty _isVisibleWhenSignedInProperty = - DependencyProperty.RegisterAttached("IsVisibleWhenSignedIn", typeof(bool?), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenSignedInPropertyChanged)); - private static void OnIsVisibleWhenSignedInPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is FrameworkElement element) @@ -56,14 +63,6 @@ private static void OnIsVisibleWhenSignedInPropertyChanged(DependencyObject d, D } } - private static void OnElementUnloaded(object sender, RoutedEventArgs e) - { - if (sender is FrameworkElement element) - { - DeregisterElement(element); - } - } - private static void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e) { var provider = ProviderManager.Instance.GlobalProvider; @@ -75,16 +74,22 @@ private static void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e) } } + private static void OnElementUnloaded(object sender, RoutedEventArgs e) + { + if (sender is FrameworkElement element) + { + DeregisterElement(element); + } + } + private static void RegisterElement(FrameworkElement element) { - ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; element.Unloaded += OnElementUnloaded; _listeningElements.Add(element); } private static void DeregisterElement(FrameworkElement element) { - ProviderManager.Instance.ProviderUpdated -= OnProviderUpdated; element.Unloaded -= OnElementUnloaded; _listeningElements.Remove(element); } From 94e16f95f4b4b072ef5e0e957a1ea20a98ed63b8 Mon Sep 17 00:00:00 2001 From: Shane Weaver Date: Tue, 8 Jun 2021 13:21:41 -0700 Subject: [PATCH 3/4] Updated IsVisibleWhenSignedIn to IsVisibleWhen --- .../Extensions/ElementExtensions.cs | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs index 7426489..d032d0d 100644 --- a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs +++ b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs @@ -15,8 +15,8 @@ public class ElementExtensions : DependencyObject { private static readonly IList _listeningElements = new List(); - private static readonly DependencyProperty _isVisibleWhenSignedInProperty = - DependencyProperty.RegisterAttached("IsVisibleWhenSignedIn", typeof(bool?), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenSignedInPropertyChanged)); + private static readonly DependencyProperty _isVisibleWhenProperty = + DependencyProperty.RegisterAttached("IsVisibleWhen", typeof(ProviderState), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenPropertyChanged)); static ElementExtensions() { @@ -30,9 +30,9 @@ static ElementExtensions() /// /// The target element. /// A nullable bool value. - public static void SetIsVisibleWhenSignedIn(FrameworkElement element, bool? value) + public static void SetIsVisibleWhen(FrameworkElement element, ProviderState value) { - element.SetValue(_isVisibleWhenSignedInProperty, value); + element.SetValue(_isVisibleWhenProperty, value); } /// @@ -40,12 +40,12 @@ public static void SetIsVisibleWhenSignedIn(FrameworkElement element, bool? valu /// /// The target element. /// A nullable bool value. - public static bool? GetIsVisibleWhenSignedIn(FrameworkElement element) + public static ProviderState GetIsVisibleWhen(FrameworkElement element) { - return (bool?)element.GetValue(_isVisibleWhenSignedInProperty); + return (ProviderState)element.GetValue(_isVisibleWhenProperty); } - private static void OnIsVisibleWhenSignedInPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnIsVisibleWhenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is FrameworkElement element) { @@ -96,25 +96,9 @@ private static void DeregisterElement(FrameworkElement element) private static void UpdateElementVisibility(FrameworkElement element, ProviderState? providerState) { - var isVisibleWhenSignedIn = GetIsVisibleWhenSignedIn(element); + var isVisibleWhen = GetIsVisibleWhen(element); - switch (isVisibleWhenSignedIn) - { - case true: - // When signed in, show the element. - element.Visibility = providerState == ProviderState.SignedIn ? Visibility.Visible : Visibility.Collapsed; - break; - - case false: - // When signed in, hide the element. - element.Visibility = providerState == ProviderState.SignedIn ? Visibility.Collapsed : Visibility.Visible; - break; - - default: - // Show the default visibility state. - element.Visibility = default; - break; - } + element.Visibility = isVisibleWhen == providerState ? Visibility.Visible : Visibility.Collapsed; } } } From d14d079cbb67f55a05018f20e189cfa44042b7d9 Mon Sep 17 00:00:00 2001 From: Shane Weaver Date: Tue, 8 Jun 2021 14:11:35 -0700 Subject: [PATCH 4/4] PR updates --- ....cs => ElementExtensions.IsVisibleWhen.cs} | 42 +++++++++---------- SampleTest/MainPage.xaml | 3 +- 2 files changed, 23 insertions(+), 22 deletions(-) rename CommunityToolkit.Graph.Uwp/Extensions/{ElementExtensions.cs => ElementExtensions.IsVisibleWhen.cs} (69%) diff --git a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.IsVisibleWhen.cs similarity index 69% rename from CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs rename to CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.IsVisibleWhen.cs index d032d0d..f19347d 100644 --- a/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.cs +++ b/CommunityToolkit.Graph.Uwp/Extensions/ElementExtensions.IsVisibleWhen.cs @@ -2,26 +2,25 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Generic; +using System.Collections.Concurrent; using CommunityToolkit.Authentication; using Windows.UI.Xaml; namespace CommunityToolkit.Graph.Uwp { /// - /// Extensions on FrameworkElement for responding to authentication changes from XAML. + /// IsVisibleWhen extension on FrameworkElement for decaring element visibility behavior in response to authentication changes. /// - public class ElementExtensions : DependencyObject + public static partial class ElementExtensions { - private static readonly IList _listeningElements = new List(); + private static readonly object _updateLock = new (); + private static readonly ConcurrentDictionary _listeningElements = new (); private static readonly DependencyProperty _isVisibleWhenProperty = DependencyProperty.RegisterAttached("IsVisibleWhen", typeof(ProviderState), typeof(FrameworkElement), new PropertyMetadata(null, OnIsVisibleWhenPropertyChanged)); static ElementExtensions() { - _listeningElements = new List(); - ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; } @@ -29,7 +28,7 @@ static ElementExtensions() /// Sets a value indicating whether an element should update its visibility based on provider state changes. /// /// The target element. - /// A nullable bool value. + /// The state in which to be visible. public static void SetIsVisibleWhen(FrameworkElement element, ProviderState value) { element.SetValue(_isVisibleWhenProperty, value); @@ -39,7 +38,7 @@ public static void SetIsVisibleWhen(FrameworkElement element, ProviderState valu /// Gets a value indicating whether an element should update its visibility based on provider state changes. /// /// The target element. - /// A nullable bool value. + /// The state in which to be visible. public static ProviderState GetIsVisibleWhen(FrameworkElement element) { return (ProviderState)element.GetValue(_isVisibleWhenProperty); @@ -49,13 +48,13 @@ private static void OnIsVisibleWhenPropertyChanged(DependencyObject d, Dependenc { if (d is FrameworkElement element) { - if (e.NewValue == null) + if (e.NewValue is ProviderState newState) { - DeregisterElement(element); + RegisterElement(element, newState); } else { - RegisterElement(element); + DeregisterElement(element); } var providerState = ProviderManager.Instance.GlobalProvider?.State; @@ -65,12 +64,13 @@ private static void OnIsVisibleWhenPropertyChanged(DependencyObject d, Dependenc private static void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e) { - var provider = ProviderManager.Instance.GlobalProvider; - var providerState = provider?.State; - - foreach (var element in _listeningElements) + lock (_updateLock) { - UpdateElementVisibility(element, providerState); + var providerState = ProviderManager.Instance.GlobalProvider?.State; + foreach (var kvp in _listeningElements) + { + UpdateElementVisibility(kvp.Key, providerState); + } } } @@ -82,23 +82,23 @@ private static void OnElementUnloaded(object sender, RoutedEventArgs e) } } - private static void RegisterElement(FrameworkElement element) + private static void RegisterElement(FrameworkElement element, ProviderState providerState) { element.Unloaded += OnElementUnloaded; - _listeningElements.Add(element); + _listeningElements.TryAdd(element, providerState); } private static void DeregisterElement(FrameworkElement element) { element.Unloaded -= OnElementUnloaded; - _listeningElements.Remove(element); + _listeningElements.TryRemove(element, out ProviderState providerState); } - private static void UpdateElementVisibility(FrameworkElement element, ProviderState? providerState) + private static void UpdateElementVisibility(FrameworkElement element, ProviderState? state) { var isVisibleWhen = GetIsVisibleWhen(element); - element.Visibility = isVisibleWhen == providerState ? Visibility.Visible : Visibility.Collapsed; + element.Visibility = isVisibleWhen == state ? Visibility.Visible : Visibility.Collapsed; } } } diff --git a/SampleTest/MainPage.xaml b/SampleTest/MainPage.xaml index 817d2bf..c31a2cd 100644 --- a/SampleTest/MainPage.xaml +++ b/SampleTest/MainPage.xaml @@ -7,7 +7,8 @@ xmlns:samples="using:SampleTest.Samples" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls" - xmlns:toolkit="using:Microsoft.Toolkit" xmlns:global="using:System.Globalization" + xmlns:toolkit="using:Microsoft.Toolkit" + xmlns:global="using:System.Globalization" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" mc:Ignorable="d">