Xamarin forms: Hide and show password feature is not working for entry

Sreejith Sree 1,251 Reputation points
2021-04-08T11:44:43.08+00:00

I have implemented the hide and show password feature for the entry component. It is not working initially, but after one hide and show, it starts working. The icons are changing but the password is not showing. This issue is only on the android platform.

My code:

Xaml.cs:

bool showPassword = true;
private void PasswordIcon_Clicked(object sender, EventArgs e)
{
    if (showPassword)
    {
        password_icon.Source = "ic_show_password_xx.png";
        password_entry.IsPassword = false;
        showPassword = false;
    }
    else
    {
        password_icon.Source = "ic_hide_password_xx.png";
        password_entry.IsPassword = true;
        showPassword = true;
    }
}

Xaml:

<StackLayout Padding="3" Orientation="Horizontal">

    <local:CustomEntry
        x:Name="password_entry"
        IsPassword="True"
        Placeholder="Password"
        Style="{StaticResource LoginEntryStyle}"/>

    <Image 
        x:Name="password_icon"
        Style="{StaticResource LoginEntryImageStyle}" 
        HorizontalOptions="End"
        Source="ic_hide_password_xx.png">
        <Image.GestureRecognizers>
            <TapGestureRecognizer
                Tapped="PasswordIcon_Clicked"
                NumberOfTapsRequired="1">
            </TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>
</StackLayout>

Instead of the bool variable, I have tried with password_entry.IsPassword, but no luck. I have uploaded a sample project here for reference.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,376 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 79,471 Reputation points Microsoft Vendor
    2021-04-08T12:20:23.893+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    You could use TriggerAction to achieve it.

       using System.ComponentModel;  
       using Xamarin.Forms;  
         
       namespace ShowHidePasswordTrigger  
       {  
           public class ShowPasswordTriggerAction : TriggerAction<ImageButton>, INotifyPropertyChanged  
           {  
               public string ShowIcon { get; set; }  
               public string HideIcon { get; set; }  
         
               bool _hidePassword = true;  
         
               public bool HidePassword  
               {  
                   set  
                   {  
                       if (_hidePassword != value)  
                       {  
                           _hidePassword = value;  
         
                           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HidePassword)));  
                       }  
                   }  
                   get => _hidePassword;  
               }  
         
               protected override void Invoke(ImageButton sender)  
               {  
                   sender.Source = HidePassword ? ShowIcon : HideIcon;  
                   HidePassword = !HidePassword;  
               }  
         
               public event PropertyChangedEventHandler PropertyChanged;  
         
           }  
       }  
    

    Then use it in the ImageVIew.

       <StackLayout VerticalOptions="Center"  
                        Padding="20">  
               <Grid>  
                <Entry Placeholder="Password"  
                       IsPassword="{Binding Source={x:Reference ShowPasswordActualTrigger}, Path=HidePassword}"/>  
         
                <ImageButton VerticalOptions="Center"  
                             Margin="0,0,10,0"  
                            HeightRequest="20"  
                            HorizontalOptions="End"  
                            Source="ic_eye_hide">  
                                <ImageButton.Triggers>  
                                     <EventTrigger Event="Clicked">  
                                          <local:ShowPasswordTriggerAction ShowIcon="ic_eye"  
                                                                           HideIcon="ic_eye_hide"  
                                                                           x:Name="ShowPasswordActualTrigger"/>  
                                      </EventTrigger>  
                               </ImageButton.Triggers>  
                 </ImageButton>  
               </Grid>  
           </StackLayout>  
    

    In your layout, you can add following code,

       <StackLayout Padding="3" Orientation="Horizontal">  
         
                                           <!--<local:CustomEntry  
                                               x:Name="password_entry"  
                                               IsPassword="True"  
                                               Text="abcdef"  
                                               Placeholder="Password"  
                                               Style="{StaticResource LoginEntryStyle}"/>  
         
                                           <Image   
                                               x:Name="password_icon"  
                                               Style="{StaticResource LoginEntryImageStyle}"   
                                               HorizontalOptions="End"  
                                               Source="ic_hide_password_xx.png">  
                                               <Image.GestureRecognizers>  
                                                   <TapGestureRecognizer  
                                                       Tapped="PasswordIcon_Clicked"  
                                                       NumberOfTapsRequired="1">  
                                                   </TapGestureRecognizer>  
                                               </Image.GestureRecognizers>  
                                           </Image>-->  
                                            
                                               <Entry Placeholder="Password"  
                                                       Grid.Column="0"  
                           IsPassword="{Binding Source={x:Reference ShowPasswordActualTrigger}, Path=HidePassword}"/>  
         
                                           <ImageButton    
                                                            Grid.Column="1"  
                                               BackgroundColor="Transparent"  
                                 Margin="0,0,10,0"  
                                HeightRequest="20"  
                                HorizontalOptions="End"  
                                Source="ic_eye_hide">  
                                                   <ImageButton.Triggers>  
                                                       <EventTrigger Event="Clicked">  
                                                           <local1:ShowPasswordTriggerAction ShowIcon="ic_eye"  
                                                                               HideIcon="ic_eye_hide"  
                                                                               x:Name="ShowPasswordActualTrigger"/>  
                                                       </EventTrigger>  
                                                   </ImageButton.Triggers>  
                                               </ImageButton>  
                                            
                                       </StackLayout>  
    

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 79,471 Reputation points Microsoft Vendor
    2021-04-08T13:46:40.93+00:00

    Please change your custom-renderer's code like following format.

    [assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
    namespace BibleGenius.Droid.Renderer
    {
        public class CustomEntryRenderer : EntryRenderer
        {
            public CustomEntryRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
            {
                base.OnElementChanged(e);
                Control?.SetBackgroundColor(Android.Graphics.Color.Transparent);
                //if (Control != null)
                //{
                //    GradientDrawable gd = new GradientDrawable();
                //    gd.SetColor(global::Android.Graphics.Color.Transparent);
                //    this.Control.SetBackgroundDrawable(gd);
                //    this.Control.SetRawInputType(InputTypes.TextFlagNoSuggestions);
                //    //Control.SetHintTextColor(ColorStateList.ValueOf(global::Android.Graphics.Color.White));
                //}
            }
        }
    }
    

    Then change the Entry to local:CustomEntry like following layout.

    <Frame 
                                    Style="{StaticResource LoginFrameStyle}"
                                    Margin="0,15,0,10">
                                    <StackLayout Padding="3" Orientation="Horizontal">
    
                                        <local:CustomEntry 
                                                    Placeholder="Password"
                                                    Grid.Column="0"
                                                    IsPassword="{Binding Source={x:Reference ShowPasswordActualTrigger}, Path=HidePassword}"/>
                                        <ImageButton  
                                              Grid.Column="1"
                                              BackgroundColor="Transparent"
                                              Margin="0,0,10,0"
                                              HeightRequest="20"
                                              HorizontalOptions="End"
                                              Source="ic_eye_hide">
                                            <ImageButton.Triggers>
                                                    <EventTrigger Event="Clicked">
                                                        <local1:ShowPasswordTriggerAction ShowIcon="ic_eye"
                                                                            HideIcon="ic_eye_hide"
                                                                            x:Name="ShowPasswordActualTrigger"/>
                                                    </EventTrigger>
                                                </ImageButton.Triggers>
                                            </ImageButton>
    
                                    </StackLayout>
                                </Frame>
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.