Reputation: 193432
How can I do this in XAML:
PSEUDO-CODE:
<TextBox Text="{Binding Password}" Type="Password"/>
so that the user sees stars or dots when he is typing in the password.
I've tried various examples which suggest PasswordChar and PasswordBox but can't get these to work.
e.g. I can do this as shown here:
<PasswordBox Grid.Column="1" Grid.Row="1"
PasswordChar="*"/>
but I of course want to bind the Text property to my ViewModel so I can send the value the bound TextBox when the button is clicked (not working with code behind), I want to do this:
<TextBox Grid.Column="1" Grid.Row="0"
Text="{Binding Login}"
Style="{StaticResource FormTextBox}"/>
<PasswordBox Grid.Column="1" Grid.Row="1"
Text="{Binding Password}"
PasswordChar="*"
Style="{StaticResource FormTextBox}"/>
But PasswordBox doesn't have a Text property.
Upvotes: 64
Views: 147113
Reputation: 1
Resolution if you don't need source value
<TextBox Text="{Binding Password}" />
private string _password = "";
public string Password {
get => _password == null ? "" : new string('*', _password.Length);
set {
_password = value; OnPropertyChanged();
}
}
Upvotes: 0
Reputation: 416
A simple resolution that worked for me was to bind the text box to the LocalPassword which displays a converted value of repeating *'s. Any entry is stored in the _localPassword variable.
<TextBox Text="{Binding LocalPassword}" />
private string _localPassword = null;
private string _localPasswordDisplayed { get => new string('*', _localPassword.Length); }
public string LocalPassword { get => _localPasswordDisplayed; set { _localPassword = value; OnPropertyChanged(); } }
Upvotes: 2
Reputation: 2417
As Tasnim Fabiha mentioned, it is possible to change font for TextBox in order to show only dots/asterisks. But I wasn't able to find his font...so I give you my working example:
<TextBox Text="{Binding Password}"
FontFamily="pack://application:,,,/Resources/#password" />
Just copy-paste won't work. Firstly you have to download mentioned font "password.ttf" link: https://github.com/davidagraf/passwd/blob/master/public/ttf/password.ttf Then copy that to your project Resources folder (Project->Properties->Resources->Add resource->Add existing file). Then set it's Build Action to: Resource.
After this you will see just dots, but you can still copy text from that, so it is needed to disable CTRL+C shortcut like this:
<TextBox Text="{Binding Password}"
FontFamily="pack://application:,,,/Resources/#password" >
<TextBox.InputBindings>
<!--Disable CTRL+C (COPY) -->
<KeyBinding Command="ApplicationCommands.NotACommand"
Key="C"
Modifiers="Control" />
<!--Disable CTRL+X (CUT) -->
<KeyBinding Command="ApplicationCommands.NotACommand"
Key="X"
Modifiers="Control" />
</TextBox.InputBindings>
<TextBox.ContextMenu>
<!--Hide context menu where you could copy/cut as well -->
<ContextMenu Visibility="Collapsed" />
</TextBox.ContextMenu>
</TextBox>
EDIT: Added Ctrl+X and Context menu disabling based on @CodingNinja comment, thank you.
Upvotes: 21
Reputation: 469
The problem with using the PasswordBox is that it is not very MVVM friendly due to the fact that it works with SecureString and therefore requires a shim to bind it to a String. You also cannot use the clipboard. While all these things are there for a reason, you may not require that level of security. Here is an alternative approach that works with the clipboard, nothing fancy. You make the TextBox text and background transparent and bind the text to a TextBlock underneath it. This textblock converts characters to * using the converter specified.
<Window.Resources>
<local:TextToPasswordCharConverter x:Key="TextToPasswordCharConverter" />
</Window.Resources>
<Grid Width="200">
<TextBlock Margin="5,0,0,0" Text="{Binding Text, Converter={StaticResource TextToPasswordCharConverter}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" FontFamily="Consolas" VerticalAlignment="Center" />
<TextBox Foreground="Transparent" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" FontFamily="Consolas" Background="Transparent" />
</Grid>
And here is the Value Converter:
class TextToPasswordCharConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new String('*', value?.ToString().Length ?? 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Make sure your Text property on your viewmodel implements INotifyPropertyChanged
Upvotes: 3
Reputation: 1238
You can make your TextBox
as customed PasswordBox
by simply adding the following value to FontFamily
property of your TextBox
control.
<TextBox
Text="{Binding Password}"
FontFamily="ms-appx:///Assets/PassDot.ttf#PassDot"
FontSize="35"/>
In my case this works perfectly. This will show dot in place of the actual text (not star(*) though).
Upvotes: 6
Reputation: 21
I did the below from the Views codebehind to set my property within the view model. Not sure if it really " breaks" the MVVM pattern but its the best and least complexe solution found.
var data = this.DataContext as DBSelectionViewModel;
data.PassKey = txtPassKey.Password;
Upvotes: 1
Reputation: 4020
Thanks Cody, that was very helpful. I've just added an example for guys using the Delegate Command in C#
<PasswordBox x:Name="PasswordBox"
Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left"
Width="300" Height="25"
Margin="6,7,0,7" />
<Button Content="Login"
Grid.Row="4" Grid.Column="1"
Style="{StaticResource StandardButton}"
Command="{Binding LoginCommand}"
CommandParameter="{Binding ElementName=PasswordBox}"
Height="31" Width="92"
Margin="5,9,0,0" />
public ICommand LoginCommand
{
get
{
return new DelegateCommand<object>((args) =>
{
// Get Password as Binding not supported for control-type PasswordBox
LoginPassword = ((PasswordBox) args).Password;
// Rest of code here
});
}
}
Upvotes: 11
Reputation: 3127
Send the passwordbox control as a parameter to your login command.
<Button Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=PasswordBox}"...>
Then you can call CType(parameter, PasswordBox).Password
in your viewmodel.
Upvotes: 12
Reputation: 1129
There's a way to bind on a PasswordBox here: PasswordBox Databinding
Upvotes: 9
Reputation: 70022
To get or set the Password in a PasswordBox, use the Password property. Such as
string password = PasswordBox.Password;
This doesn't support Databinding as far as I know, so you'd have to set the value in the codebehind, and update it accordingly.
Upvotes: 39