Hi, I'm having a problem with triggering the Completed event in custom control on iOS.
I'm implementing the CustomRadEntry as a custom control of type Entry.
public class CustomRadEntry : Entry
{
public event EventHandler OnCompleted;
public CustomRadEntry()
{ }
public void InvokeCompletedEvent()
{
OnCompleted?.Invoke(this, null);
}
}
CustomRadEntryHandler.cs
public partial class CustomRadEntryHandler
{
public static IPropertyMapper<CustomRadEntry, CustomRadEntryHandler> PropertyMapper = new PropertyMapper<CustomRadEntry, CustomRadEntryHandler>(EntryHandler.ViewMapper)
{
[nameof(CustomRadEntry.Text)] = MapText
};
public static CommandMapper<CustomRadEntry, CustomRadEntryHandler> CommandMapper = new(ViewCommandMapper)
{ };
public CustomRadEntryHandler() : base(PropertyMapper, CommandMapper)
{ }
}
CustomRadEntryHandler.MaciOS.cs
public partial class CustomRadEntryHandler : EntryHandler
{
protected override MauiCustomRadEntry CreatePlatformView()
{
return new MauiCustomRadEntry(VirtualView);
}
protected override void ConnectHandler(MauiTextField platformView)
{
base.ConnectHandler(platformView);
}
protected override void DisconnectHandler(MauiTextField platformView)
{
base.DisconnectHandler(platformView);
}
}
Beneath it, there is also an implementation for iOS named MauiCustomRadEntry which inherits from MauiTextField.
public class MauiCustomRadEntry : MauiTextField
{
private CustomRadEntry _customEntry;
public MauiCustomRadEntry(IEntry entry)
{
_customEntry = (CustomRadEntry)entry;
AddDoneButton();
//TODO: Test if using _customEntry in this constructor is correct.
CustomBorderUITextFieldDelegate textFieldDelegate = new CustomBorderUITextFieldDelegate(_customEntry);
WeakDelegate = textFieldDelegate;
}
private void AddDoneButton()
{
var toolbar = new UIToolbar(new RectangleF(0.0f, 0.0f, 50.0f, 44.0f));
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate
{
ResignFirstResponder();
_customEntry.InvokeCompletedEvent();
});
toolbar.Items = new[] {
new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),
doneButton};
InputAccessoryView = toolbar;
}
}
public class CustomBorderUITextFieldDelegate : UITextFieldDelegate
{
private WeakReference element;
internal Entry Element => this.element.IsAlive ? (Entry)this.element.Target : (Entry)null;
public CustomBorderUITextFieldDelegate(Entry element) => this.element = new WeakReference((object)element);
public override void EditingStarted(UITextField textField) => this.Element?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, (object)true);
public override bool ShouldReturn(UITextField textField)
{
textField.ResignFirstResponder();
if (Element is CustomRadEntry customRadEntry)
{
customRadEntry.InvokeCompletedEvent();
}
//this.Element.InvokeCompletedEvent();
return false;
}
public override void EditingEnded(UITextField textField, UITextFieldDidEndEditingReason reason) => this.Element?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, (object)false);
}
inside the MauiCustomRadEntry constructor, I assigned a WeakDelegate to a custom Delegate. Details of implementation is in the attached project. The Page containing and testing this control is CustomRadEntryPage.xaml.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="dummyProj.Pages.CustomRadEntryPage"
xmlns:controls="clr-namespace:dummyProj.CustomControls"
Title="CustomRadEntryPage">
<Grid>
<controls:CustomRadEntry
HorizontalOptions="Center"
Text="heLLO WORLD"
OnCompleted="CustomRadEntry_OnCompleted"
ReturnType="Next"
/>
</Grid>
</ContentPage>
CustomRadEntryPage.xaml.cs
public CustomRadEntryPage()
{
InitializeComponent();
}
void CustomRadEntry_OnCompleted(System.Object sender, System.EventArgs e)
{
Console.Write("Hit Done");
}
If you run into the issue when an exception of delegate occurs, please add this line to CreateMauiApp() of AppDelegate.cs
UIApplication.CheckForEventAndDelegateMismatches = false;
When I hit Done, I expect it to trigger the ShouldReturn() of the delegate. In fact, it doesn't. I need it to invoke the completed event. Please have a look and can you give me a work-around to make this work?