IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

TextBox.KeyDown : remplacer un caractère


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut TextBox.KeyDown : remplacer un caractère
    Hello,

    Je suis en train de créer une DecimalTextBox qui, comme son nom l'indique, servira à faire encoder des nombres décimaux par les utilisateurs (car le DecimalUpDown de Xceed laisse vraiment à désirer...).

    Bref, tout va très bien sauf que, plutôt que de me contenter de faire une validation avec ValidationRule de ce qui a été encoder, je voudrais aussi limité la saisie clavier. Ils pourront toujours encoder des conneries en faisant des copier-coller mais la ValidationRule est là pour leur dire qu'ils font de la merde.

    Du coup, pour limiter la saisie clavier, j'ai fait ceci (vous pouvez voir que j'ai testé plusieurs choses déjà) :
    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Private _test As Boolean = True
     
            Private Sub tb_KeyDown(sender As Object, e As KeyEventArgs)
                Dim newKey = e.Key
                If _allowedNumKeys.Contains(e.Key) AndAlso Keyboard.IsKeyToggled(Key.NumLock) Then
                    'ok
                ElseIf _allowedShiftedKeys.Contains(e.Key) AndAlso (Keyboard.IsKeyDown(Key.LeftShift) OrElse Keyboard.IsKeyDown(Key.RightShift) OrElse Keyboard.IsKeyToggled(Key.CapsLock)) Then
                    'ok
                ElseIf (e.Key = Key.OemMinus OrElse e.Key = Key.Subtract) AndAlso MinValue < 0 Then
                    'ok
                ElseIf (e.Key = Key.OemComma OrElse e.Key = Key.OemPeriod OrElse e.Key = Key.Decimal) AndAlso Not _test Then
                    'ok
                ElseIf (e.Key = Key.OemComma OrElse e.Key = Key.OemPeriod OrElse e.Key = Key.Decimal) AndAlso _test Then
                    _test = False
                    Dim c = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.ToCharArray()(0)
                    e.Handled = True
                    'If tb.Text Is Nothing Then
                    ' tb.Text = ""
                    'End If
                    'Dim pos = tb.SelectionStart
                    'If pos = tb.Text.Length Then
                    ' tb.Text &= c.ToString
                    'Else
                    ' tb.Text = tb.Text.Insert(pos, c)
                    'End If
     
     
                    'newKey = Key.Decimal
     
     
                    'tb.Select(pos + 1, 0)
                    Dim key As Key
                    If c = "," Then
                        key = Key.OemComma
                    ElseIf c = "." Then
                        key = Key.OemPeriod
                    End If
                    Dim args = New KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key)
                    args.RoutedEvent = Keyboard.KeyDownEvent
                    InputManager.Current.ProcessInput(args)
                    _test = True
                Else
                    e.Handled = True
                End If
            End Sub
    Ca marche très bien pour interdire la saisie de caractère comme les lettres par exemple. Par contre, pas moyen de faire un remplacement de caractère pour avoir le bon séparateur décimal en fonction de la culture de l'utilisateur. Histoire que s'il met un point alors qu'il faut une virgule, bin ça mette la virgule pour lui. (c'est surtout car la touche décimal du clavier ne donne pas le bon séparateur... un truc de fou)

    Bref, auriez-vous une astuce pour parvenir à remplacer un caractère sur l'événement KeyDown d'un control de type TextBox en WPF svp ?

    Merci d'avance.

    EDIT : Si nécessaire, voici le code xaml du controle. Des fois que la méthode de validation aurait un impact...
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <UserControl x:Class="Controls.NumericTextBox.DecimalTextBox" x:Name="DecimalTextBox"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:InnoFramework.Wpf"
                 xmlns:vr="clr-namespace:InnoFramework.Wpf.ValidationRules"
                 mc:Ignorable="d" >
        <UserControl.Resources>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="BorderBrush" Value="Red"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </UserControl.Resources>
        <Grid>
            <TextBox x:Name="tb" KeyDown="tb_KeyDown">
                <TextBox.Text>
                    <Binding Path="Value" UpdateSourceTrigger="PropertyChanged" ElementName="DecimalTextBox">
                        <Binding.ValidationRules>
                            <vr:StringToDecimalValidationRule ValidationStep="RawProposedValue"/>
                            <DataErrorValidationRule/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
                <Validation.ErrorTemplate>
                    <ControlTemplate>
                        <StackPanel>
                            <AdornedElementPlaceholder x:Name="textBox"/>
                            <TextBlock Text="{Binding CurrentItem.ErrorContent}" Foreground="Red" Background="LightYellow"/>
                        </StackPanel>
                    </ControlTemplate>
                </Validation.ErrorTemplate>
            </TextBox>
        </Grid>
    </UserControl>

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut Complément d'infos
    Hello,

    Je viens de remarquer que si je commente les lignes 19 à 26 du code xaml (le binding du text avec la propriété Value de mon usercontrol), alors le remplacement s'effectue correctement...

    Et si je laisse le binding mais que je commente le noeud Binding.ValidationRules, alors le remplacement s'effectue à "moitié". Cad que, tant que le nombre que j'encode est entier, je ne peux pas mettre de virgule à la fin. Par contre, je peux mettre une virgule où je veux entre deux caractères déjà présent. Et à partir du moment où j'ai déjà une virgule dans le nombre, alors je peux en mettre à la fin si je veux.. (rendant le nombre non valide on est d'accord).

    Bref, je pige pas trop le principe là...

  3. #3
    Membre averti Avatar de _champy_
    Homme Profil pro
    Chef de projet progiciel patrimoine route/tram/aeroport
    Inscrit en
    Novembre 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projet progiciel patrimoine route/tram/aeroport
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2017
    Messages : 26
    Par défaut
    Si Xceed as une implémentation limite à ce niveau c'est certainement que ce n'est pas si simple (tu gère le KeyDown mais quid d'un CTRL+V par exemple)

    Je te conseil tous simplement de lire leur source :
    https://github.com/xceedsoftware/wpf...mericUpDown.cs

    Cela devrais te donner des idées d'implémentation.

Discussions similaires

  1. Réponses: 3
    Dernier message: 27/04/2015, 22h48
  2. Remplacer un caractère après saisie dans TextBox
    Par melouille56 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 11/10/2007, 15h12
  3. [WinForms]scanner une textbox et remplacer des caractères
    Par totoche9 dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 18/08/2006, 14h40
  4. Fonction permettant de remplacer des caractères
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 06/09/2004, 15h48
  5. Remplacer un caractère
    Par Mvu dans le forum ASP
    Réponses: 5
    Dernier message: 20/07/2004, 09h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo