web-dev-qa-db-fra.com

Comment puis-je transformer une zone de texte en "zone de mot de passe" et afficher des étoiles lors de l'utilisation de MVVM?

Comment puis-je faire cela en XAML:

(PSEUDO-CODE: _

<TextBox Text="{Binding Password}" Type="Password"/>

de sorte que l'utilisateur voit des étoiles ou des points lorsqu'il tape le mot de passe.

J'ai essayé divers exemples qui suggèrent PasswordChar et PasswordBox mais ne parviennent pas à les faire fonctionner.

par exemple. Je peux le faire comme indiqué ici :

<PasswordBox Grid.Column="1" Grid.Row="1"
    PasswordChar="*"/>

mais je veux bien sûr lier la propriété Text à mon ViewModel pour pouvoir envoyer la valeur à la TextBox liée lorsque le bouton est cliqué (ne fonctionne pas avec le code derrière), je souhaite le faire:

<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}"/>

Mais PasswordBox n'a pas de propriété Text.

38
Edward Tanguay

Pour obtenir ou définir le mot de passe dans une PasswordBox, utilisez la propriété Password. Tel que

string password = PasswordBox.Password;

Autant que je sache, cela ne prend pas en charge la liaison de données. Vous devez donc définir la valeur dans codeback et la mettre à jour en conséquence.

30
Brandon

Envoyez le contrôle passwordbox en tant que paramètre à votre commande de connexion. 

<Button Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=PasswordBox}"...>

Ensuite, vous pouvez appeler CType(parameter, PasswordBox).Password dans votre modèle de vue.

10
Cody C

Il existe un moyen de lier une PasswordBox ici: PasswordBox Databinding

9
gimpy

Merci Cody, c'était très utile. Je viens d'ajouter un exemple pour les gars utilisant la commande déléguée en 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
        });
   }
}
5
Kwex

Vous pouvez créer votre TextBox comme personnalisé PasswordBox en ajoutant simplement la valeur suivante à la propriété FontFamily de votre contrôle TextBox

<TextBox
    Text="{Binding Password}"
    FontFamily="ms-appx:///Assets/PassDot.ttf#PassDot"
    FontSize="35"/>

Dans mon cas, cela fonctionne parfaitement. Cela montrera un point à la place du texte actuel (pas une étoile (*) cependant).

3
Tasnim Fabiha

J'ai fait ci-dessous le code de vues derrière pour définir ma propriété dans le modèle de vue. Vous ne savez pas vraiment si cela "casse" le modèle MVVM, mais c’est la solution la meilleure et la moins complexe.

  var data = this.DataContext as DBSelectionViewModel;

        data.PassKey = txtPassKey.Password;
1
Daniel_Uns

Comme Tasnim Fabiha l’a mentionné, il est possible de changer la police de caractères pour TextBox afin d’afficher uniquement les points/astérisques. Mais je n'ai pas pu trouver sa police ... alors je vous donne mon exemple de travail:

<TextBox Text="{Binding Password}" 
     FontFamily="pack://application:,,,/Resources/#password" />

Juste copier-coller ne fonctionnera pas. Tout d’abord, vous devez télécharger la police mentionnée "password.ttf" Link: https://github.com/davidagraf/passwd/blob/master/public/ttf/password.ttf Copiez ensuite le dans le dossier Ressources de votre projet (Projet-> Propriétés-> Ressources-> Ajouter une ressource-> Ajouter un fichier existant). Puis définissez son action de construction sur: Ressource.

Après cela, vous ne verrez que des points, mais vous pouvez toujours copier du texte à partir de cela, il est donc nécessaire de désactiver le raccourci CTRL + C comme ceci:

<TextBox Text="{Binding Password}" 
     FontFamily="pack://application:,,,/Resources/#password" > 
    <TextBox.InputBindings>
        <!--Disable CTRL+C -->
        <KeyBinding Command="ApplicationCommands.NotACommand"
            Key="C"
            Modifiers="Control" />
    </TextBox.InputBindings>
</TextBox>
1
ssamko

Le problème lié à l'utilisation de PasswordBox est qu'il n'est pas très convivial avec MVVM car il fonctionne avec SecureString et nécessite par conséquent un shim pour le lier à une chaîne. Vous ne pouvez pas non plus utiliser le Presse-papiers. Bien que toutes ces choses soient là pour une raison, vous n’avez peut-être pas besoin de ce niveau de sécurité. Voici une approche alternative qui fonctionne avec le presse-papiers, rien d’extraordinaire. Vous rendre le texte et l'arrière-plan TextBox transparents et liez le texte à un TextBlock en dessous. Ce bloc de texte convertit les caractères en * en utilisant le convertisseur spécifié.

<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>

Et voici le convertisseur de valeur:

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();
    }
}

Assurez-vous que votre propriété Text sur votre viewmodel implémente INotifyPropertyChanged.

0
David