[UWP] Implementation of Switch.OnColor (#4883)
authorGerald Versluis <github@geraldversluis.nl>
Thu, 17 Jan 2019 00:03:05 +0000 (01:03 +0100)
committerSamantha Houts <samhouts@users.noreply.github.com>
Thu, 17 Jan 2019 00:03:05 +0000 (16:03 -0800)
* Implemented Switch.OnColor on UWP

* Processed first feedback

* Removed hardcoded opacity

* Update Xamarin.Forms.Platform.UAP/SwitchRenderer.cs

Co-Authored-By: jfversluis <github@geraldversluis.nl>
* Update Xamarin.Forms.Platform.UAP/SwitchRenderer.cs

Co-Authored-By: jfversluis <github@geraldversluis.nl>
Xamarin.Forms.Controls/CoreGalleryPages/SwitchCoreGalleryPage.cs
Xamarin.Forms.CustomAttributes/TestAttributes.cs
Xamarin.Forms.Platform.UAP/SwitchRenderer.cs

index 5d9ebcf..f7e53ba 100644 (file)
@@ -19,7 +19,25 @@ namespace Xamarin.Forms.Controls
                        base.Build (stackLayout);
 
                        var isToggledContainer = new ValueViewContainer<Switch> (Test.Switch.IsToggled, new Switch (), "IsToggled", value => value.ToString ());
-                       Add (isToggledContainer);
+
+                       var onColoredSwitch = new Switch() { OnColor = Color.HotPink };
+
+                       var onColorContainer = new ValueViewContainer<Switch>(Test.Switch.OnColor, onColoredSwitch, "OnColor", value => value.ToString());
+                       var changeOnColorButton = new Button
+                       {
+                               Text = "Change OnColor"
+                       };
+                       var clearOnColorButton = new Button
+                       {
+                               Text = "Clear OnColor"
+                       };
+                       changeOnColorButton.Clicked += (s, a) => { onColoredSwitch.OnColor = Color.Red; };
+                       clearOnColorButton.Clicked += (s, a) => { onColoredSwitch.OnColor = Color.Default; };
+                       onColorContainer.ContainerLayout.Children.Add(changeOnColorButton);
+                       onColorContainer.ContainerLayout.Children.Add(clearOnColorButton);
+
+                       Add(isToggledContainer);
+                       Add(onColorContainer);
                }
        }
 }
\ No newline at end of file
index 9ab8f12..dc37df9 100644 (file)
@@ -713,7 +713,8 @@ namespace Xamarin.Forms.CustomAttributes
 
                public enum Switch
                {
-                       IsToggled
+                       IsToggled,
+                       OnColor
                }
 
                public enum TimePicker
index 08ab5df..a83ffe4 100644 (file)
@@ -1,21 +1,28 @@
 using System.ComponentModel;
+using System.Linq;
 using Windows.UI.Xaml;
 using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Media.Animation;
+using Windows.UI.Xaml.Shapes;
 
 namespace Xamarin.Forms.Platform.UWP
 {
        public class SwitchRenderer : ViewRenderer<Switch, ToggleSwitch>
        {
+               Brush _originalOnHoverColor;
+               Brush _originalOnColorBrush;
+
                protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
                {
                        base.OnElementChanged(e);
-
                        if (e.NewElement != null)
                        {
                                if (Control == null)
                                {
                                        var control = new ToggleSwitch();
                                        control.Toggled += OnNativeToggled;
+                                       control.Loaded += OnControlLoaded;
                                        control.ClearValue(ToggleSwitch.OnContentProperty);
                                        control.ClearValue(ToggleSwitch.OffContentProperty);
 
@@ -40,10 +47,18 @@ namespace Xamarin.Forms.Platform.UWP
                        {
                                UpdateFlowDirection();
                        }
+                       else if (e.PropertyName == Switch.OnColorProperty.PropertyName)
+                               UpdateOnColor();
                }
 
                protected override bool PreventGestureBubbling { get; set; } = true;
 
+               void OnControlLoaded(object sender, RoutedEventArgs e)
+               {
+                       UpdateOnColor();
+                       Control.Loaded -= OnControlLoaded;
+               }
+
                void OnNativeToggled(object sender, RoutedEventArgs routedEventArgs)
                {
                        ((IElementController)Element).SetValueFromRenderer(Switch.IsToggledProperty, Control.IsOn);
@@ -53,5 +68,54 @@ namespace Xamarin.Forms.Platform.UWP
                {
                        Control.UpdateFlowDirection(Element);
                }
+
+               void UpdateOnColor()
+               {
+                       if (Control == null)
+                               return;
+
+                       var grid = Control.GetChildren<Windows.UI.Xaml.Controls.Grid>().FirstOrDefault();
+                       var groups = Windows.UI.Xaml.VisualStateManager.GetVisualStateGroups(grid);
+                       foreach (var group in groups)
+                       {
+                               if (group.Name != "CommonStates")
+                                       continue;
+
+                               foreach (var state in group.States)
+                               {
+                                       if (state.Name != "PointerOver")
+                                               continue;
+
+                                       foreach (var timeline in state.Storyboard.Children.OfType<ObjectAnimationUsingKeyFrames>())
+                                       {
+                                               var property = Storyboard.GetTargetProperty(timeline);
+                                               var target = Storyboard.GetTargetName(timeline);
+                                               if (target == "SwitchKnobBounds" && property == "Fill")
+                                               {
+                                                       var frame = timeline.KeyFrames.First();
+
+                                                       if (_originalOnHoverColor == null)
+                                                               _originalOnHoverColor = (Brush)frame.Value;
+
+                                                       if (!Element.OnColor.IsDefault)
+                                                               frame.Value = new SolidColorBrush(Element.OnColor.ToWindowsColor()) { Opacity = _originalOnHoverColor.Opacity };
+                                                       else
+                                                               frame.Value = _originalOnHoverColor;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       var rect = Control.GetDescendantsByName<Windows.UI.Xaml.Shapes.Rectangle>("SwitchKnobBounds").First();
+
+                       if (_originalOnColorBrush == null)
+                               _originalOnColorBrush = rect.Fill;
+
+                       if (!Element.OnColor.IsDefault)
+                               rect.Fill = new SolidColorBrush(Element.OnColor.ToWindowsColor());
+                       else
+                               rect.Fill = _originalOnColorBrush;
+               }
        }
-}
\ No newline at end of file
+}