Search code examples
c#.net-coremauimaui-windows

How to style a property of a custom control in .net MAUI which derives a button?


I created a simple custom control by deriving a button. The aim was to add a hover functionality when the user hover the mouse over the button, And yes - I realize this won't work with touch devices which I'm ok with it.

Next I wanted to style my UiButton but I found out that upon executing the app it encounter a problem and cannot recognize the custom property which I written and so it cannot execute.

However when styling custom controls that derive from ContentView, everything works ok. But I wish to derive the button class.. When I explicitly set the 'HooverBackgroundColor' in my xaml view - it recognize it and works as expected.

I realize this could be a bug .net Maui itself but I'm not sure.
Any Idea how to resolve it?
(if it is a bug in .net Maui - where do I report about it?)

Here is my code:

public class UiButton : Button
{
    public static readonly BindableProperty HooverBackgrounColorProperty =
        BindableProperty.Create(nameof(HooverBackgroundColor),
            typeof(Color), typeof(UiButton), Colors.LightYellow,
            BindingMode.OneWay);

    protected Color originalBackgroundColor;

    public Color HooverBackgroundColor
    {
        get { return (Color)GetValue(HooverBackgrounColorProperty); }
        set { SetValue(HooverBackgrounColorProperty, value); }
    }

    public UiButton()
    {
        var pointerGestureRecognizer = new PointerGestureRecognizer();
        pointerGestureRecognizer.PointerEntered += PointerGestureRecognizer_PointerEntered;
        pointerGestureRecognizer.PointerExited += PointerGestureRecognizer_PointerExited;
        GestureRecognizers.Add(pointerGestureRecognizer);
    }

    private void PointerGestureRecognizer_PointerEntered(object sender, PointerEventArgs e)
    {
        originalBackgroundColor = BackgroundColor;
        BackgroundColor = HooverBackgroundColor;
    }


    private void PointerGestureRecognizer_PointerExited(object sender, PointerEventArgs e)
    {
        BackgroundColor = originalBackgroundColor;
        originalBackgroundColor = null;
    }
}

And here is the resource dictionary code:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:ui="clr-namespace:MyExample.Frontend.Ui">

    <Color x:Key="ForegroundNotice">#FF008080</Color>
    <Color x:Key="ForegroundSubtle">#FF006060</Color>
    <Color x:Key="ForegroundHoover">Cyan</Color>

    <Style x:Key="FormButton" TargetType="{x:Type ui:UiButton}">
        <Setter Property="TextColor" Value="{StaticResource ForegroundNotice}"/>
        <Setter Property="BackgroundColor" Value="Transparent"/>
        <Setter Property="BorderWidth" Value="2"/>
        <Setter Property="BorderColor" Value="{StaticResource ForegroundNotice}"/>
        <!-- Maui Bug: it is not recognizing a custom property if the class derived from is Button -->
        <!--<Setter Property="HooverBackgroundColor" Value="{StaticResource ForegroundHoover}"/>-->
    </Style>

</ResourceDictionary>

Solution

  • Your code works just as it should be. The problem is that you have misspelled HooverBackgroundColorProperty. It is missing a d at the end of Background.

    Regarding to derive from controls. Of course you can and should do that. Normally you do it together with handlers. See how it can be done in this Answer