1
votes

I have the following code for my custom renderer. The Element in use is a Label and I'm trying to set a background colour with rounded edges.

[assembly: ExportRenderer(typeof(RoundedLabel), typeof(RoundedLabelCustomRenderer))]
namespace MyNamespace.UWP.CustomRenderers
{
public class RoundedLabelCustomRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            var view = (RoundedLabel)e.NewElement;

            Children.Clear();

            var border = new Border
            {
                CornerRadius = new CornerRadius(view.RoundedCornerRadius),
                Background = new SolidColorBrush(view.RoundedBackgroundColor.ToWindows()),
                Child = Control
            };

            Control.Padding = new Windows.UI.Xaml.Thickness(
                                 view.InsidePadding.Left, 
                                 view.InsidePadding.Top, 
                                 view.InsidePadding.Right, 
                                 view.InsidePadding.Bottom);
            Control.Foreground = new SolidColorBrush(view.TextColor.ToWindows());

            Children.Add(border);
        }
    }
}
}

For the likes of a button (which is a composite object in UWP), this would be fine and if it was in "pure" XAML, something like

<Border background="gray" cornerradius="12">
     <TextBlock />
</Border>

would do the job.

I'm just having fun and games trying to reconcile the two snippets together.

Any pointers to what I'm doing wrong would be appreciated.

2

2 Answers

2
votes

It is difficult to realize your requirement with custom LabelRenderer. Because there is no such interface to modify background color and Radius. However, you can do that via custom View. And then in UWP client project you could use UserControl to render the control you want.

CustomNewLabelControl.cs

public class CustomNewLabelControl : View
{
    public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
propertyName: "LabelText",
eturnType: typeof(string),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(string));

    public string LabelText
    {
        get { return (string)GetValue(LabelTextProperty); }
        set { SetValue(LabelTextProperty, value); }
    }

    public static readonly BindableProperty LabelRadiusProperty = BindableProperty.Create(
propertyName: "LabelRadius",
eturnType: typeof(double),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(double));

    public double LabelRadius
    {
        get { return (double)GetValue(LabelRadiusProperty); }
        set { SetValue(LabelRadiusProperty, value); }
    }

    public static readonly BindableProperty LabelBackgroundProperty = BindableProperty.Create(
propertyName: "LabelBackground",
eturnType: typeof(Color),
declaringType: typeof(CustomNewLabelControl),
defaultValue: default(Color));

    public Color LabelBackground
    {
        get { return (Color)GetValue(LabelBackgroundProperty); }
        set { SetValue(LabelBackgroundProperty, value); }
    }
}

NewLabelControl.xaml.cs

 public sealed partial class NewLabelControl : UserControl
 {
     public NewLabelControl()
     {
         this.InitializeComponent();
         this.DataContext = this;
     }

     public string Text
     {
         get { return (string)GetValue(TextProperty); }
         set { SetValue(TextProperty, value); }
     }

     public static readonly DependencyProperty TextProperty =
         DependencyProperty.Register("Text", typeof(string), typeof(NewLabelControl), new PropertyMetadata(0));

     public SolidColorBrush LabelBackground
     {
         get { return (SolidColorBrush)GetValue(LabelBackgroundProperty); }
         set { SetValue(LabelBackgroundProperty, value); }
     }


     public static readonly DependencyProperty LabelBackgroundProperty =
         DependencyProperty.Register("LabelBackground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));

     public CornerRadius LabelRadius
     {
         get { return (CornerRadius)GetValue(LabelRadiusProperty); }
         set { SetValue(LabelRadiusProperty, value); }
     }

     public static readonly DependencyProperty LabelRadiusProperty =
         DependencyProperty.Register("LabelRadius", typeof(CornerRadius), typeof(NewLabelControl), new PropertyMetadata(0));

     public SolidColorBrush LabelForeground
     {
         get { return (SolidColorBrush)GetValue(LabelForegroundProperty); }
         set { SetValue(LabelForegroundProperty, value); }
     }


     public static readonly DependencyProperty LabelForegroundProperty =
         DependencyProperty.Register("LabelForeground", typeof(SolidColorBrush), typeof(NewLabelControl), new PropertyMetadata(0));
 }

NewLabelControl.xaml

<Grid>
    <Border CornerRadius="{Binding LabelRadius}" Background="{Binding LabelBackground}">
        <TextBlock Text="{Binding Text}" Foreground="{Binding LabelForeground }" />
    </Border>
</Grid>

CustomNewLabelRanderer.cs

internal class CustomNewLabelRanderer : ViewRenderer<CustomNewLabelControl, NewLabelControl>
{
    protected override void OnElementChanged(ElementChangedEventArgs<CustomNewLabelControl> e)
    {
        base.OnElementChanged(e);
        if (Control == null)
        {
            SetNativeControl(new NewLabelControl());
        }
        if (e.OldElement != null)
        {
        }
        if (e.NewElement != null)
        {
            Control.Text = Element.LabelText;
            Control.LabelRadius = new Windows.UI.Xaml.CornerRadius(Element.LabelRadius);

            Color color = Element.LabelBackground;
            Control.LabelBackground = new Windows.UI.Xaml.Media.SolidColorBrush(
                Windows.UI.Color.FromArgb(
                    (byte)(color.A * 255),
                    (byte)(color.R * 255),
                    (byte)(color.G * 255),
                    (byte)(color.B * 255)));
        }
    }
}

Usage

<local:CustomNewLabelControl LabelText="Welcome to Xamarin Forms!" 
           LabelBackground="Gray" LabelRadius="5"
           VerticalOptions="Center"
           HorizontalOptions="Center" />

enter image description here

1
votes

What you're probably looking for is Frame (which actually is rendered as a Border on UWP). Frame let's you set both background color and corner radius:

<Frame BackgroundColor="Grey" CornerRadius="12" HasShadow="false" Padding="0">
     <Label />
</Frame>

Frame has a drop shadow and padding set to 20 by default, so you'll have to removed those for your desired result.