Search code examples
xamarin.formsxamarin.iosgradientxamarin.uwp

Gradient as a Buttons BorderColor?


I want to set a gradient border color for a Xamarin.Forms button. How can I do that?

Current:
no-gradient-solid-color

Desire:
gradient

A few options rise to the top through Google, but none seem to be platform independent AND work for Buttons.

To name a couple:
-Using a WebView and setting the gradient background using CSS (source: Xamarin forums)
-XFGloss looks to be a outstandingly well-designed solution but, unfortunately its scope, as written, appears to be Cell views and Layouts only. Likewise even if this does work for Buttons, it appears to be iOS & Android only.

The desire is an iOS & UWP compatible solution for applying gradients to a Button s BorderColor.

Did some preliminary digging and have yet to find anything for Buttons. A thousand apologies if I missed a post on SO regarding Button BorderColor property gradients.


Solution

  • You could custom ButtomRender to realize gradient border in Xamarin Forms. Edit the BorderColor property in OnElementChanged override method. You could pass a LinearGradientBrush to Control.BorderBrush to realize this feature within UWP. For detail, please refer the following code.

    UWP

    public class MyButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                if (Element.IsSet(Button.BorderColorProperty) && Element.BorderColor != (Color)Button.BorderColorProperty.DefaultValue)
                {
                    UpdateBorderColor();
                }
    
            }
        }
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e.PropertyName == Button.BorderColorProperty.PropertyName)
            {
                UpdateBorderColor();
            }
        }
        void UpdateBorderColor()
        {
            Control.BorderBrush = Element.BorderColor != Color.Default ? Element.BorderColor.ToGradientBrush() : (Brush)Windows.UI.Xaml.Application.Current.Resources["ButtonBorderThemeBrush"];
        }
    
    }
    internal static class ConvertExtensions
    {
        public static Brush ToGradientBrush(this Color color)
        {
            var GradientBrush = new LinearGradientBrush();
            GradientBrush.StartPoint = new Windows.Foundation.Point(0.5, 0);
            GradientBrush.EndPoint = new Windows.Foundation.Point(0.5, 1);
            GradientBrush.GradientStops.Add(new GradientStop() { Color = Windows.UI.Colors.LightGray, Offset = 0.0 });
            GradientBrush.GradientStops.Add(new GradientStop() { Color = color.ToWindowsColor(), Offset = 1.0 });
            return GradientBrush;
        }
    
        public static Windows.UI.Color ToWindowsColor(this Color color)
        {
            return Windows.UI.Color.FromArgb((byte)(color.A * 255), (byte)(color.R * 255), (byte)(color.G * 255), (byte)(color.B * 255));
        }
    
    }
    

    IOS

    public class MyButtonRenderer : ButtonRenderer
    {
       CAGradientLayer gradient;
       CAShapeLayer shape;
       protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
    
            gradient = new CAGradientLayer(); 
            // add start color          
            gradient.Colors = new CGColor[] { ((GradientButton)Element).StartColor.ToCGColor(), Element.BorderColor.ToCGColor() };
    
           shape = new CAShapeLayer();
           shape.LineWidth = (nfloat)(Element.BorderWidth);
           shape.StrokeColor = UIColor.Black.CGColor;
           shape.FillColor = UIColor.Clear.CGColor;
           gradient.Mask = shape;
    
           Control.Layer.AddSublayer(gradient);
           Control.Layer.BorderColor = UIColor.Clear.CGColor;
        }
    
         public override void Draw(CGRect rect)
         {
           base.Draw(rect);
    
           shape.Path = UIBezierPath.FromRect(rect).CGPath;
           gradient.Frame = rect;
         }
    }
    

    enter image description here

    This is code sample that contain UWP and IOS platform please check.