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?
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?
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.
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:
You can use BoxView instead of Frame
<Grid Margin="10,10,80,10">
<BoxView Color="#CCE4FF"
CornerRadius="10,10,10,0"
HorizontalOptions="Fill"
VerticalOptions="Fill" />
<Grid Padding="10">
<Label Text="This is my message"
FontSize="14"
TextColor="#434343"/>
</Grid>
</Grid>
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);
}
}
}
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>