'Xamarin Frame only have a single rounded corner
Simple question. I need a frame with only one rounded corner, instead of all four. How can I only round one of the corners of a frame (top right in my case)?
Another way to phrase it: How can I set the cornerradius of only one corner of a frame?
Solution 1:[1]
Another way it to use custom render for frame.
1.Create class name CustomFrame, inherit Frame class, add BindableProperty CornerRadiusProperty in PCL.
public class CustomFrame: Frame
{
public static new readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CustomFrame), typeof(CornerRadius), typeof(CustomFrame));
public CustomFrame()
{
// MK Clearing default values (e.g. on iOS it's 5)
base.CornerRadius = 0;
}
public new CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
}
create CustomFrameRender in Android.
using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer; [assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))] namespace Demo1.Droid { class CustomFrameRenderer : FrameRenderer { public CustomFrameRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Frame> e) { base.OnElementChanged(e); if (e.NewElement != null && Control != null) { UpdateCornerRadius(); } } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == nameof(CustomFrame.CornerRadius) || e.PropertyName == nameof(CustomFrame)) { UpdateCornerRadius(); } } private void UpdateCornerRadius() { if (Control.Background is GradientDrawable backgroundGradient) { var cornerRadius = (Element as CustomFrame)?.CornerRadius; if (!cornerRadius.HasValue) { return; } var topLeftCorner = Context.ToPixels(cornerRadius.Value.TopLeft); var topRightCorner = Context.ToPixels(cornerRadius.Value.TopRight); var bottomLeftCorner = Context.ToPixels(cornerRadius.Value.BottomLeft); var bottomRightCorner = Context.ToPixels(cornerRadius.Value.BottomRight); var cornerRadii = new[] { topLeftCorner, topLeftCorner, topRightCorner, topRightCorner, bottomRightCorner, bottomRightCorner, bottomLeftCorner, bottomLeftCorner, }; backgroundGradient.SetCornerRadii(cornerRadii); } } } }
3.using custonframe in forms.
<StackLayout>
<controls:CustomFrame
BackgroundColor="Red"
CornerRadius="0,30,0,0"
HeightRequest="100"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="100" />
</StackLayout>
More detailed info about this, please refer to:
Solution 2:[2]
The easy way is to use the Nuget PancakeView.
You can specify the CornerRadius in each vertice, achieving the desired effect:
Example:
<yummy:PancakeView BackgroundColor="Orange"CornerRadius="60,0,0,60"/>
You can read more in the official page.
Solution 3:[3]
Solution 4:[4]
This is for UWP renderer
I've used the solutions from Cherry Bu - MSFT and changed it for UWP. In my project im using it in Android, iOS and UWP and it is working fine.
using System.ComponentModel;
using Windows.UI.Xaml.Media;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(yourNamespace.UWP.CustomFrameRenderer))]
namespace yourNamespace.UWP
{
public class CustomFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
UpdateCornerRadius();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(CustomFrame.CornerRadius) ||
e.PropertyName == nameof(CustomFrame))
{
UpdateCornerRadius();
}
}
private void UpdateCornerRadius()
{
var radius = ((CustomFrame)this.Element).CornerRadius;
Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(radius.TopLeft, radius.TopRight, radius.BottomRight, radius.BottomLeft);
}
}
}
Solution 5:[5]
simple solution i have used is to set another frame behind the rounded frame something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.8*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
</Grid.RowDefinitions>
<Frame
Grid.Row="4"
Padding="0"
BackgroundColor="Green"
CornerRadius="0"/>
<Frame
Grid.Row="3"
Grid.RowSpan="2"
Padding="0"
BackgroundColor="Green"
HasShadow="True"
CornerRadius="20">
</Frame>
</Grid>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Cherry Bu - MSFT |
| Solution 2 | Bruno Caceiro |
| Solution 3 | David Jesus |
| Solution 4 | xiawi |
| Solution 5 | ???? ??? ?????? |

