xamarinxamarin.androidxamarin.forms

How to change password masking character in Xamarin forms - Entry


I've currently faced a rather simple issue which eventually put me to a dead end. I am building an application that uses Xamarin Forms and want to change a masking character when user enters password from a bullet to an asterisk.

For entering password I'm using Entry control in Portable lib project in my content page (in VS2017 professional):

<Entry x:Name="Entry_Password" Placeholder="Password" IsPassword="True" />

I know that I probably should create a custom Renderer in Android project for this one, but would really appreciate how to do it for this specific purpose.


Solution

  • Am sure the converter answer will work , but as a personal preference i dont like it. this looks like a renderer job to me .

    and here is how i would do it(example only in android because i dont have ios, but its fairly simple to implement it there)

    Usage Xamarin forms

            <controls:PasswordBox Placeholder="Password"/>
    

    The Renderer (Android)

    [assembly: ExportRenderer(typeof(PasswordBox), typeof(PasswordBoxRenderer))]
    namespace PasswordAsterisk.Droid.Renderers
    {
    public class PasswordBoxRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
    
            if (Control != null)
            {
                Control.InputType = Android.Text.InputTypes.TextVariationPassword |
                          Android.Text.InputTypes.ClassText;
    
                Control.TransformationMethod = new HiddenPasswordTransformationMethod();
            }
        }
    }
    internal class HiddenPasswordTransformationMethod : Android.Text.Method.PasswordTransformationMethod
    {
        public override Java.Lang.ICharSequence GetTransformationFormatted(Java.Lang.ICharSequence source, Android.Views.View view)
        {
            return new PasswordCharSequence(source);
        }
    }
    
    internal class PasswordCharSequence : Java.Lang.Object, Java.Lang.ICharSequence
    {
        private Java.Lang.ICharSequence _source;
        public PasswordCharSequence(Java.Lang.ICharSequence source)
        {
            _source = source;
        }
    
        public char CharAt(int index)
        {
            return '*';
        }
    
        public int Length()
        {
            return _source.Length();
        }
    
        public Java.Lang.ICharSequence SubSequenceFormatted(int start, int end)
        {
            return _source.SubSequenceFormatted(start, end); 
        }
    
        public IEnumerator<char> GetEnumerator()
        {
            return _source.GetEnumerator();
        }
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _source.GetEnumerator();
        }
    }
    }
    

    full source code example in GitHub