1

Hot to set each corner radius for the Frame? It can be set all by one, but I to set each of them individually, 2 rounded 2 normal.

Johnny
  • 8,939
  • 2
  • 28
  • 33
  • 2
    Where is your attempt? – ray Jan 18 '19 at 10:44
  • The default `Frame` widget does not allow individual corners to be changed, you can of course do this via a custom renderer per platform. i.e. on iOS, you can add a mask layer to the control, the https://stackoverflow.com/a/43877570/4984832 – SushiHangover Jan 18 '19 at 10:50

4 Answers4

7

No hacks, there is a very simple solution:

Use the nuget package Xamarin.Forms.PancakeView.

enter image description here

How to use it?

  1. Install the nuget package Xamarin.Forms.PancakeView.
  2. Then you need to do is tell our XAML page where it can find the PancakeView, which is done by adding the following attribute to our ContentPage:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     xmlns:yummy="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView">
       ...
</ContentPage>
  1. Just smack a PancakeView onto that page and you're all set:
<yummy:PancakeView BackgroundColor="#bc91d7" CornerRadius="60,0,0,60" IsClippedToBounds="true" HorizontalOptions="FillAndExpand" HeightRequest="150">
   <Image Source="unicorn.png" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Aspect="AspectFill" />
</yummy:PancakeView>
David Jesus
  • 1,981
  • 2
  • 29
  • 34
  • Just and FYI , according to the publishers of this component, it is going by the wayside as they have other projects to work on. It already no longer works correctly in UWP apps. – George M Ceaser Jr Sep 27 '21 at 20:52
2

A very hacky attempt with xaml, and you can still notice artifacts on the borders, but for a quick go-go why not..

    <Grid>

        <Frame Margin="0,0,0,20" HasShadow="False" BorderColor="Transparent" CornerRadius="12" HorizontalOptions="Fill" VerticalOptions="Fill" BackgroundColor="Gray"/>
        <Frame Margin="1,1,1,20" HasShadow="False" BorderColor="Transparent" CornerRadius="11" HorizontalOptions="Fill" VerticalOptions="Fill" BackgroundColor="White"/>
        <Frame Margin="0,20,0,0" VerticalOptions="Fill" HasShadow="False" BorderColor="Transparent" CornerRadius="2" HorizontalOptions="Fill" BackgroundColor="Gray" />
        <Frame Margin="1,20,1,1" VerticalOptions="Fill"  HasShadow="False" BorderColor="Transparent" CornerRadius="2" HorizontalOptions="Fill" BackgroundColor="White" />
        <BoxView Margin="1.75,15,1.75,15" HorizontalOptions="Fill" VerticalOptions="Fill" BackgroundColor="White" HeightRequest="19" StyleId="hide background"/>

        <ContentView Margin="8" x:Name="MainContainer">
            <StackLayout >
                <Label TextColor="DimGray" Text="This is your main container"/>
                <Label TextColor="DimGray" Text="Put stuff here"/>
            </StackLayout>
        </ContentView>

    </Grid>

enter image description here

Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50
0

You need to create a custom renderer on each platform. I don't know if you can control the radius individually but you can control whether the corner adheres to the radius or not.

Firstly, you need a custom class in your shared project that will act as your custom control ...

using System;
using Xamarin.Forms;

namespace MyApp.Controls
{
    public class CustomFrame : Frame
    {
        // ---------------------------------------------------------------------------------------------------------------
        public static readonly BindableProperty CornerRadiusTopLeftProperty = BindableProperty.Create(
            propertyName: "CornerRadiusTopLeft",
            returnType: typeof(bool),
            declaringType: typeof(CustomFrame),
            defaultValue: true,
            defaultBindingMode: BindingMode.TwoWay
        );

        public bool CornerRadiusTopLeft
        {
            get { return (bool)GetValue(CornerRadiusTopLeftProperty); }
            set { base.SetValue(CornerRadiusTopLeftProperty, value); }
        }

        // ---------------------------------------------------------------------------------------------------------------
        public static readonly BindableProperty CornerRadiusTopRightProperty = BindableProperty.Create(
            propertyName: "CornerRadiusTopRight",
            returnType: typeof(bool),
            declaringType: typeof(CustomFrame),
            defaultValue: true,
            defaultBindingMode: BindingMode.TwoWay
        );

        public bool CornerRadiusTopRight
        {
            get { return (bool)GetValue(CornerRadiusTopRightProperty); }
            set { base.SetValue(CornerRadiusTopRightProperty, value); }
        }

        // ---------------------------------------------------------------------------------------------------------------
        public static readonly BindableProperty CornerRadiusBottomLeftProperty = BindableProperty.Create(
            propertyName: "CornerRadiusBottomLeft",
            returnType: typeof(bool),
            declaringType: typeof(CustomFrame),
            defaultValue: true,
            defaultBindingMode: BindingMode.TwoWay
        );

        public bool CornerRadiusBottomLeft
        {
            get { return (bool)GetValue(CornerRadiusBottomLeftProperty); }
            set { base.SetValue(CornerRadiusBottomLeftProperty, value); }
        }

        // ---------------------------------------------------------------------------------------------------------------
        public static readonly BindableProperty CornerRadiusBottomRightProperty = BindableProperty.Create(
            propertyName: "CornerRadiusBottomRight",
            returnType: typeof(bool),
            declaringType: typeof(CustomFrame),
            defaultValue: true,
            defaultBindingMode: BindingMode.TwoWay
        );

        public bool CornerRadiusBottomRight
        {
            get { return (bool)GetValue(CornerRadiusBottomRightProperty); }
            set { base.SetValue(CornerRadiusBottomRightProperty, value); }
        }
    }
}

You then need to create the renderer on each platform. I haven't done the Android side yet but this is what you need for iOS ...

using System;

using CoreAnimation;

using MyApp.iOS.CustomRenderers;
using Foundation;
using MyApp.Controls;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace MyApp.iOS.CustomRenderers
{
    public class CustomFrameRenderer : FrameRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);

            if (Element != null)
            {
                var element = Element as CustomFrame;

                int result = 0;

                if (element.CornerRadiusTopLeft)
                    result += (int)CACornerMask.MinXMinYCorner;

                if (element.CornerRadiusTopRight)
                    result += (int)CACornerMask.MaxXMinYCorner;

                if (element.CornerRadiusBottomLeft)
                    result += (int)CACornerMask.MinXMaxYCorner;

                if (element.CornerRadiusBottomRight)
                    result += (int)CACornerMask.MaxXMaxYCorner;

                Layer.MaskedCorners = (CACornerMask)result;
            };
        }
    }
}

You're then able to make use of it in your XAML file as a custom control.

Add the namespace to your page ...

xmlns:customControls="clr-namespace:MyApp.Controls"

... then add your custom frame ...

<customControls:CustomFrame BackgroundColor="White" CornerRadius="10" HasShadow="false"            
        CornerRadiusBottomLeft="false" CornerRadiusBottomRight="false" VerticalOptions="Start" HorizontalOptions="FillAndExpand" Padding="15">

    <!-- Add your other elements here -->
</customControls:CustomFrame>

I hope that helps you. Good luck with the Android renderer, I'm sure it's not hard, just haven't gotten to it yet.

Skin
  • 9,085
  • 2
  • 13
  • 29
0

using Xamarin.Forms.PancakeView.

 <yummy:PancakeView BackgroundColor="#2DA6EA"  WidthRequest="300" HorizontalOptions="Start" CornerRadius="0,30,0,30">
                    <StackLayout>
                    <Label TextColor="White" Margin="10,0,0,0" FontSize="15" Text="Welcome"/>
                    <Label TextColor="White" Margin="10,0,0,0"  FontSize="20" Text="Dolapo"/>
                </StackLayout>
                </yummy:PancakeView>