In.Net Maui here is the complete custom handlers for the record reference.
Create Interface base IView //ICustomButton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomButtonLib.Controls
{
public interface ICustomButton : IView
{
public string Text { get; }
public string TexColor { get; }
}
}
CustomButton BindableProperty //CustomButton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomButtonLib.Controls
{
public class CustomButton : View, ICustomButton
{
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(CustomButton),
string.Empty);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly BindableProperty TextColorProperty =
BindableProperty.Create(
nameof(TextColor),
typeof(Color),
typeof(CustomButton),
Colors.ForestGreen);
public Color TextColor
{
get { return (Color)GetValue(TextProperty); }
set { SetValue(TextColorProperty, value); }
}
}
}
Create a partial CustomButtonHandler //CustomButtonHandler.cs
using CustomButtonLib.Controls;
using Microsoft.Maui.Handlers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomButtonLib.Handlers
{
public partial class CustomButtonHandler
{
public static PropertyMapper<ICustomButton, CustomButtonHandler> CustomButtonMapper =
new PropertyMapper<ICustomButton, CustomButtonHandler>(ViewHandler.ViewMapper)
{
[nameof(ICustomButton.Text)] = MapText,
[nameof(ICustomButton.TextColor)] = MapTextColor,
};
public CustomButtonHandler() : base(CustomButtonMapper)
{
}
public CustomButtonHandler(PropertyMapper mapper = null) : base(mapper ?? CustomButtonMapper)
{
}
}
}
.NetStandard partial class //CustomButtonHandler.Standard.cs
using CustomButtonLib.Controls;
using Microsoft.Maui.Handlers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomButtonLib.Handlers
{
public partial class CustomButtonHandler : ViewHandler<ICustomButton, object>
{
protected override object CreatePlatformView()
{
throw new NotImplementedException();
}
public static void MapText(CustomButtonHandler handler, ICustomButton iCustomButton)
{
}
public static void MapTextColor(CustomButtonHandler handler, ICustomButton iCustomButton)
{
}
}
}
Create specific handler in Platform Folder (Ex. Windows) //CustomButtonHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Maui.Handlers;
using Microsoft.UI.Xaml;
namespace CustomButtonLib.Handlers
{
public partial class CustomButtonHandler : ViewHandler<ICustomButton, FrameworkElement>
{
protected override FrameworkElement CreatePlatformView()
{
return new Microsoft.UI.Xaml.Controls.Button();
}
protected override void ConnectHandler(Microsoft.UI.Xaml.Controls.Button nativeView)
{
// Subscribe to events
base.ConnectHandler(nativeView);
}
protected override void DisconnectHandler(Microsoft.UI.Xaml.Controls.ButtonnativeView)
{
// Unsubscribe from events
base.DisconnectHandler(nativeView);
}
public static void MapText(CustomButtonHandler handler, ICustomButton iCustomButton)
{
if (handler != null &&
handler.PlatformView != null &&
handler.PlatformView is Microsoft.UI.Xaml.Controls.Button bttn)
{
bttn.Content = iCustomButton.Text;
}
}
[MissingMapper] // Add this to indicate if not available on this platform.
public static void MapTextColor(CustomButtonHandler handler, ICustomButton iCustomButton)
{
}
}
}
Continue On Other Platforms for successful build.
Optional => Add Project sdk ItemGroups, so no need to Add Platform Directive. (Ex. #if Windows).
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) != true ">
<Compile Remove="Platforms\iOS\*.cs" />
<None Include="Platforms\iOS\*.cs" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-maccatalyst')) != true ">
<Compile Remove="Platforms\MacCatalyst\*.cs" />
<None Include="Platforms\MacCatalyst\*.cs" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-android')) != true ">
<Compile Remove="Platforms\Android\*.cs" />
<None Include="Platforms\Android\*.cs" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
<Compile Remove="Platforms\Windows\*.cs" />
<None Include="Platforms\Windows\*.cs" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) == true OR $(TargetFramework.StartsWith('net6.0-maccatalyst')) == true OR $(TargetFramework.StartsWith('net6.0-android')) == true OR $(TargetFramework.Contains('-windows')) == true">
<Compile Remove="**\*.Standard.cs" />
<None Include="**\*.Standard.cs" />
<Compile Remove="**\Standard\**\*.cs" />
<None Include="**\Standard\**\*.cs" />
</ItemGroup>
<!-- ANDROID -->
<PropertyGroup Condition="$(TargetFramework.StartsWith('net6.0-android'))">
<DefineConstants>$(DefineConstants);MONOANDROID</DefineConstants>
</PropertyGroup>
<!-- IOS -->
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0-ios' ">
<DefineConstants>$(DefineConstants);IOS</DefineConstants>
</PropertyGroup>
<!-- MACCATALYST -->
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0-maccatalyst' ">
<DefineConstants>$(DefineConstants);MACCATALYST;IOS</DefineConstants>
</PropertyGroup>
<!-- WINDOWS -->
<PropertyGroup Condition="$(TargetFramework.Contains('-windows')) == true ">
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<DefineConstants>WINDOWS;$(DefineConstants)</DefineConstants>
</PropertyGroup>
Last Register Custom Button on Builder Services => Extensions
public static MauiAppBuilder ConfigureLibrary(this MauiAppBuilder builder)
{
builder
.ConfigureMauiHandlers(handlers =>
{
handlers.AddLibraryHandlers();
});
return builder;
}
public static IMauiHandlersCollection AddLibraryHandlers(this IMauiHandlersCollection handlers)
{
handlers.AddTransient(typeof(CustomButton), h => new CustomButtonHandler());
return handlers;
}
// Usage .ConfigureLibrary()