Home > Blockchain >  Draw string on a button
Draw string on a button

Time:07-05

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.

CodePudding user response:

You could create your Custom button and then set the text alignment via custom renderer.

[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(ButtonCustomRenderer))]//set the Button as your custom button
namespace App3.Droid
{
public class ButtonCustomRenderer : ButtonRenderer
{
    public ButtonCustomRenderer(Context context) : base(context)
    {

    }
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
    {
        base.OnElementChanged(e);
        Control.Gravity = GravityFlags.End // Set the horizontal text alignment to right 
                       | GravityFlags.Bottom; // Set the vertical text alignment to bottom
    }
  }
}

enter image description here

CodePudding user response:

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); }
    }
}
  • Related