1

Following the documentation here, I created a handler to set the horizontal content alignment on a button

This is the shared platform partial class:

public partial class IconButtonHandler
{
    public static IPropertyMapper<IconButton, IconButtonHandler> PropertyMapper = new PropertyMapper<IconButton, IconButtonHandler>(ViewHandler.ViewMapper)
    {
        [nameof(IconButton.HorizontalContentAlignment)] = IconButtonHandler.MapHorizontalAlignment
    };

    public IconButtonHandler() : base(PropertyMapper)
    {
    }
}

This is the android implementation

public partial class IconButtonHandler : ViewHandler<IconButton, AppCompatButton>
{
    public IconButtonHandler([NotNull] IPropertyMapper mapper, CommandMapper commandMapper = null) : base(mapper, commandMapper)
    {
    }
    
    protected override AppCompatButton CreatePlatformView()
    {
        var button =  new AppCompatButton(Context);

        return button;
    }

    protected override void ConnectHandler(AppCompatButton platformView)
    {
        base.ConnectHandler(platformView);
    }

    protected override void DisconnectHandler(AppCompatButton platformView)
    {
        platformView.Dispose();
        base.DisconnectHandler(platformView);
    }

    public static void MapHorizontalAlignment(IconButtonHandler handler, IconButton view)
    {
        handler.PlatformView.Gravity = view.HorizontalContentAlignment.ToDroidHorizontalGravity();
    }
}

This is adding the handler in MauiProgram.cs:

.ConfigureMauiHandlers(handlers =>
            { 
                handlers.AddHandler(typeof(IconButton), typeof(IconButtonHandler));
            })

This is IconButton, it just inherits from button and adds this:

public TextAlignment HorizontalContentAlignment
{
    get => (TextAlignment)GetValue(HorizontalContentAlignmentProperty);
    set => SetValue(HorizontalContentAlignmentProperty, value);
}

public static readonly BindableProperty HorizontalContentAlignmentProperty = BindableProperty.Create(
    nameof(IconButton),        // the name of the bindable property
    typeof(TextAlignment),     // the bindable property type
    typeof(IconButton),   // the parent object type
    TextAlignment.Center);      // the default value for the property

The buttons are invisible on Android. When I comment out adding the handler, they show up again. I feel like the problem is in CreatePlatformView, because If I create a blank handler with no logic except for this

protected override AppCompatButton CreatePlatformView()
{
    var button =  new AppCompatButton(Context);

    return button;
}

The buttons still don't show up.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Adam Diament
  • 4,290
  • 3
  • 34
  • 55
  • 1
    IIRC, when you call base with a property map dictionary, you REPLACE the existing mapper dictionary. But you need existing button properties. Instead, add to it using Mapper.AppendToMapping. Example: https://github.com/FreakyAli/Maui.FreakyControls/blob/master/MAUI.FreakyControls/MAUI.FreakyControls/Shared/FreakyEntry/FreakyEntryHandler.cs – ToolmakerSteve Jun 30 '23 at 15:25
  • 1
    Also, make sure your Android partial class is in same namespace as shared one, not in a .Android namespace. – ToolmakerSteve Jun 30 '23 at 15:34
  • 1
    Ok thanks @ToolmakerSteve - it seems to work now. So in summary, when my custom ui element inherits directly from a Maui one e.g `IconButton : Button`, I should inherit the Maui Handler for that element e.g `IconButtonHandler : ButtonHandler` and use `Mapper.AppendToMapping` instead of create a whole new propertymapper dict. In contrast, if I had an a custom view that is a composite of other views, I should use my original approach? It seems to work - I wish the Maui docs were more clear about this! – Adam Diament Jul 02 '23 at 11:39

0 Answers0