[FIXED] Draw string on a button

Issue

I want do draw a custom string on the bottom right of an button with an PlatformEffect. Prefer to use an effect to be more flexible and apply this only to specific buttons and not application wide. The buttons are created dynamically without xaml.

Is this possible or do i need to create a custom button + renderer?

Thanks.

Solution

I solved it by creating a renderer which overrides the Draw method.

public class HotkeyButtonRenderer : ButtonRenderer
{
    HotkeyButton element;

    public HotkeyButtonRenderer(Context ctx) : base(ctx)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);
        element = Element as HotkeyButton;
        SetWillNotDraw(false);
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (element != null && e.PropertyName == HotkeyButton.HotkeyTextProperty.PropertyName)
        {
            Invalidate();
        }
    }

    public override void Draw(Canvas canvas)
    {
        base.Draw(canvas);
        if (element != null && !string.IsNullOrEmpty(element.HotkeyText))
        {
            string textToDraw = string.Format("({0})", element.HotkeyText);
            float textSize = Control.TextSize / 1.5f;
            SizeF measuredTextSize = GetTextSize(textToDraw, element.FontFamily, textSize);
            float x = 5;
            float y = Height-measuredTextSize.Height/2;

            canvas.DrawText(textToDraw,
                x,
                y,
                new TextPaint
                {
                    Color = element.BorderColor.ToAndroid(),
                    TextSize = textSize
                });
        }
    }

    private SizeF GetTextSize(string text, string fontFamily, float textSize)
    {
        var textPaint = new SKPaint(new SKFont(SKTypeface.FromFamilyName(fontFamily), textSize));
        SKRect textBounds = new SKRect(); 
        textPaint.MeasureText(text, ref textBounds);
        return new SizeF(textBounds.Width, textBounds.Height);
    }
}

public class HotkeyButton : Button
{
    public static readonly BindableProperty HotkeyTextProperty = BindableProperty.Create(
        propertyName: nameof(HotkeyText),
        returnType: typeof(string),
        declaringType: typeof(MobileEntry),
        defaultValue: string.Empty);

    public string HotkeyText
    {
        get { return (string)GetValue(HotkeyTextProperty); }
        set { SetValue(HotkeyTextProperty, value); }
    }
}

Answered By – MrSpt

Answer Checked By – Candace Johnson (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published