Change return to be next/done key in Xamarin Forms Shared Project

后端 未结 4 1775
北海茫月
北海茫月 2020-12-13 18:53

Is it possible to change the text in the \'return\' key on the keyboard to be either \'next\' or \'done\'? I have a login form with username and password. I want the return

4条回答
  •  温柔的废话
    2020-12-13 19:31

    Here is an alternative approach, but similar to the solution of SushiHangover. It includes UWP support:

    ReturnType.cs in PCL

    public enum ReturnType
    {
        Go,
        Next,
        Done,
        Send,
        Search
    }
    

    BaseEntry.cs in PCL

    public class BaseEntry : Entry
    {
        // Need to overwrite default handler because we cant Invoke otherwise
        public new event EventHandler Completed;
    
        public static readonly BindableProperty ReturnTypeProperty = BindableProperty.Create(
            nameof(ReturnType),
            typeof(ReturnType),
            typeof(BaseEntry),
            ReturnType.Done, 
            BindingMode.OneWay
        );
    
        public ReturnType ReturnType
        {
            get { return (ReturnType)GetValue(ReturnTypeProperty); }
            set { SetValue(ReturnTypeProperty, value); }
        }
    
        public void InvokeCompleted()
        {
            if (this.Completed != null)
                this.Completed.Invoke(this, null);
        }
    }
    

    BaseEntryRenderer.cs for Android

    public class BaseEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
    
            BaseEntry entry = (BaseEntry)this.Element;
    
            if(this.Control != null)
            {
                if(entry != null)
                {
                    SetReturnType(entry);
    
                    // Editor Action is called when the return button is pressed
                    Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
                    {
                        if (entry.ReturnType != ReturnType.Next)
                            entry.Unfocus();
    
                        // Call all the methods attached to base_entry event handler Completed
                        entry.InvokeCompleted();
                    };
                }
            }
        }
    
        private void SetReturnType(BaseEntry entry)
        {
            ReturnType type = entry.ReturnType;
    
            switch (type)
            {
                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;
            }
        }
    }
    

    BaseEntryRenderer.cs for iOS

    public class BaseEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
    
            BaseEntry entry = (BaseEntry)this.Element;
    
            if (this.Control != null)
            {
                if(entry != null)
                {
                    SetReturnType(entry);
    
                    Control.ShouldReturn += (UITextField tf) =>
                    {
                        entry.InvokeCompleted();
                        return true;
                    };
                }
            }
        }
    
        private void SetReturnType(BaseEntry entry)
        {
            ReturnType type = entry.ReturnType;
    
            switch (type)
            {
                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;
            }
        }
    }
    

    BaseEntryRenderer.cs for UWP

    public class BaseEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
    
            BaseEntry entry = (BaseEntry)this.Element;
    
            if(this.Control != null)
            {
                if(entry != null)
                {
                    this.Control.KeyDown += (object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs eventArgs) =>
                    {
                        if (eventArgs.Key == Windows.System.VirtualKey.Enter)
                        {
                            entry.InvokeCompleted();
                            // Make sure to set the Handled to true, otherwise the RoutedEvent might fire twice
                            eventArgs.Handled = true;
                        }
                    };
                }
            }
        }
    }
    

    On UWP it seems not be possible to change the return key to next/done/... You need to add ExportRenderer attributes yourself for all custom renderers.

    Usage

    XAML file

    
    
    

    Code behind file:

    this.username.Completed += (object sender, EventArgs e) => this.password.Focus();
    

    Based on this source.

提交回复
热议问题