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à) :
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)
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
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>
Partager