Done button not firing Completed event on Xamarin

2019-08-01 02:52发布

问题:

After I've added the Done button on iOS numeric keyboard in Xamarin Forms, I encountered another problem: the Done button not firing Completed event (like return button does). On my way to implement this, I found the following code on Xamarin Forums:

using System;
using System.Drawing;
using System.Reflection;
using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using UIKit;
using KeyboardTest.iOS;
using KeyboardTest;

[assembly: ExportRenderer(typeof(EntryDone), typeof(EntryDoneRenderer))]

namespace KeyboardTest.iOS
{
public class EntryDoneRenderer : EntryRenderer
{
// used to cache the MethodInfo so we only have the reflection hit once
private MethodInfo baseEntrySendCompleted = null;
public EntryDoneRenderer ()
{
}

protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
    base.OnElementChanged (e);

    if (this.Element.Keyboard == Keyboard.Numeric) 
    {
        // only want the Done on the numeric keyboard type
        UIToolbar toolbar = new UIToolbar (new RectangleF (0.0f, 0.0f, (float)Control.Frame.Size.Width, 44.0f));

        var doneButton = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
            this.Control.ResignFirstResponder ();
            Type baseEntry = this.Element.GetType();
            if(baseEntrySendCompleted==null)
            {
                // use reflection to find our method
                baseEntrySendCompleted = baseEntry.GetMethod("SendCompleted",BindingFlags.NonPublic|BindingFlags.Instance);
            }

            try 
            {
                baseEntrySendCompleted.Invoke(this.Element,null);
            } 
            catch (Exception ex) 
            {
                // handle the invoke error condition    
            }

        });

        toolbar.Items = new UIBarButtonItem[] {
            new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),
            doneButton
        };

        this.Control.InputAccessoryView = toolbar;
    }
}
}
}

I don't know why, but I receive the error:

System.NullReferenceException: Object reference not set to an instance of an object
  at myGame.iOS.DoneEntryRenderer.<OnElementChanged>m__0 (System.Object , System.EventArgs ) [0x0005d] in /Users/silviu/Projects/myGame/iOS/DoneEntry.cs:37 

On that line I have the code: baseEntrySendCompleted.Invoke(this.Element, null);

I’ve tried to debug the problem and I found that the SendCompleted method does not exist, but I don’t understand how to solve this problem in the lastest version of Xamarin, because I think on the moment when that guy posted the code, worked.

Thanks!

回答1:

SendCompleted() was actually added for IEntryController so you don't need to use reflection for this any longer. In fact it appears that way no longer works. Just call SendCompleted() directly from your button press like so.

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));

        toolbar.Items = new[]
        {
            new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
            new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate {
                Control.ResignFirstResponder();
                ((IEntryController)Element).SendCompleted();
            })
        };

        this.Control.InputAccessoryView = toolbar;
    }