Xamarin Forms Entry invoke Completed event
Solution 1
Fixed the issue by changing
entryExt.InvokeCompleted();
inside the EditorAction to
((IEntryController)Element).SendCompleted();
which sends out the completed event back to the Entry base class.
Solution 2
I've implemented a similar method of implementing this that allows the Return
button to be extended to implement any type: Go, Next, Done, Send and Search.
Sample App
Here is a Xamarin.Forms app where I've implemented this approach. Feel free to download the repo and try it out!
1. Create Custom Entry
In the Xamarin.Forms PCL, create a Custom Entry
public class EntryWithCustomKeyboardReturnButton : Entry
{
public new event EventHandler Completed;
public static readonly BindableProperty ReturnTypeProperty =
BindableProperty.Create<EntryWithCustomKeyboardReturnButton, ReturnType>(s => s.ReturnType, ReturnType.Done);
public ReturnType ReturnType
{
get { return (ReturnType)GetValue(ReturnTypeProperty); }
set { SetValue(ReturnTypeProperty, value); }
}
public void InvokeCompleted()
{
Completed?.Invoke(this, null);
}
}
public enum ReturnType
{
Go,
Next,
Done,
Send,
Search
}
2. Create iOS Custom Renderer
In the iOS PCL, create this custom renderer
[assembly: ExportRenderer(typeof(EntryWithCustomKeyboardReturnButton), typeof(EntryWithCustomKeyboardReturnButtonCustomRenderer))]
namespace Sample.iOS
{
public class EntryWithCustomKeyboardReturnButtonCustomRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
var customEntry = Element as EntryWithCustomKeyboardReturnButton;
if (Control != null && customEntry != null)
{
SetKeyboardButtonType(customEntry.ReturnType);
Control.ShouldReturn += (UITextField tf) =>
{
customEntry?.InvokeCompleted();
return true;
};
}
}
void SetKeyboardButtonType(ReturnType returnType)
{
switch (returnType)
{
case ReturnType.Go:
Control.ReturnKeyType = UIReturnKeyType.Go;
break;
case ReturnType.Next:
Control.ReturnKeyType = UIReturnKeyType.Next;
break;
case ReturnType.Send:
Control.ReturnKeyType = UIReturnKeyType.Send;
break;
case ReturnType.Search:
Control.ReturnKeyType = UIReturnKeyType.Search;
break;
case ReturnType.Done:
Control.ReturnKeyType = UIReturnKeyType.Done;
break;
default:
Control.ReturnKeyType = UIReturnKeyType.Default;
break;
}
}
}
}
3. Create Android Custom Renderer
In the Android PCL, create this custom renderer
[assembly: ExportRenderer(typeof(EntryWithCustomKeyboardReturnButton), typeof(EntryWithCustomKeyboardReturnButtonCustomRenderer))]
namespace Sample.Droid
{
public class EntryWithCustomKeyboardReturnButtonCustomRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
var customEntry = Element as EntryWithCustomKeyboardReturnButton;
if (Control != null && customEntry != null)
{
SetKeyboardButtonType(customEntry.ReturnType);
Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
{
if (customEntry?.ReturnType != ReturnType.Next)
customEntry?.Unfocus();
customEntry?.InvokeCompleted();
};
}
}
void SetKeyboardButtonType(ReturnType returnType)
{
switch (returnType)
{
case ReturnType.Go:
Control.ImeOptions = ImeAction.Go;
Control.SetImeActionLabel("Go", ImeAction.Go);
break;
case ReturnType.Next:
Control.ImeOptions = ImeAction.Next;
Control.SetImeActionLabel("Next", ImeAction.Next);
break;
case ReturnType.Send:
Control.ImeOptions = ImeAction.Send;
Control.SetImeActionLabel("Send", ImeAction.Send);
break;
case ReturnType.Search:
Control.ImeOptions = ImeAction.Search;
Control.SetImeActionLabel("Search", ImeAction.Search);
break;
default:
Control.ImeOptions = ImeAction.Done;
Control.SetImeActionLabel("Done", ImeAction.Done);
break;
}
}
}
}
4. Implement the Completed Event for Entry in Xamarin.Forms PCL
Here is a link to some sample code that shows how to implement the Completed
Event in the Xamarin.Forms PCL.
Related videos on Youtube
MegaMiley
Updated on September 14, 2022Comments
-
MegaMiley over 1 year
I'm currently working on a login and registration page within Xamarin Forms and after changing the done button of the keyboard to next and go on the last one I am no longer receiving the Completed event on Android (working fine on iOS). In the custom renderer I can catch the Control.EditorAction event which now acts the same as the Completed event but I can't seem to invoke the Completed event on the entry itself.
Within the EntryRenderer
Control.EditorAction += (object sender, TextView.EditorActionEventArgsargs) => { if (entryExt.ReturnKeyType != ReturnKeyTypes.Next) entryExt.Unfocus(); // Call all the methods attached to base_entry event handler Completed entryExt.InvokeCompleted(); };
And within the EntryExt (which extends the Entry directly)
public void InvokeCompleted() { Completed?.Invoke(this, null); }
But the Completed event cannot be invoked due to the error
Error CS0070: The event `Xamarin.Forms.Entry.Completed' can only appear on the left hand side of += or -= when used outside of the type `Xamarin.Forms.Entry'
Is there a way to invoke the Completed event? I'd rather not have a separate event handler for this within my views.