Ci-dessous vous trouverez le code pour une propriété jointe qui peut être utilisée comme ceci pour empêcher tout sauf "(" ou ")" d'être supprimé du TextBox, point.
<TextBox my:TextBoxRestriction.RestrictDeleteTo="()" ... />
Cela gérer correctement toutes les mises à jour de la souris et du clavier, tels que:
- Utilisation de la touche Suppr avec plusieurs caractères sélectionnés
- Utilisation de la touche Retour arrière
- Utilisation de Ctrl- X pour couper
- En cliquant sur le bouton "Couper" de votre barre de menu
Pour cette raison, il est beaucoup plus puissant que d'intercepter simplement PreviewKeyDown.
Ceci empêche également la suppression de tout BYT « (» ou «) » en attribuant directement à la propriété .Text, donc cela échouera:
textBox.Text = "Good morning";
En raison de cette classe TextBoxRestriction contient également une autre propriété attachée appelé UnrestrictedText qui, lorsqu'il est défini, peut mettre à jour la propriété Text en ignorant les restrictions.Cela peut être définie dans le code à l'aide TextBoxRestriction.SetUnrestrictedText
ou liée aux données comme ceci: Dans la mise en œuvre ci-dessous, UnrestrictedText ne fonctionne que
<TextBox my:TextBoxRestriction.RestrictDeleteTo="()"
my:TextBoxRestriction.UnrestrictedText="{Binding PropertyNameHere}" />
lorsque RestrictDeleteTo est également définie. Une implémentation complète peut être effectuée qui enregistre le gestionnaire d'événements chaque fois que la propriété est définie et enregistre le gestionnaire dans une troisième propriété jointe pour un désenregistrement ultérieur. Mais pour vos besoins actuels, c'est probablement inutile.
Voici la mise en œuvre comme promis:
public class TextBoxRestriction : DependencyObject
{
// RestrictDeleteTo: Set this to the characters that may be deleted
public static string GetRestrictDeleteTo(DependencyObject obj) { return (string)obj.GetValue(RestrictDeleteToProperty); }
public static void SetRestrictDeleteTo(DependencyObject obj, string value) { obj.SetValue(RestrictDeleteToProperty, value); }
public static readonly DependencyProperty RestrictDeleteToProperty = DependencyProperty.RegisterAttached("RestrictDeleteTo", typeof(string), typeof(TextBoxRestriction), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
var box = (TextBox)obj;
box.TextChanged += (obj2, changeEvent) =>
{
var oldText = GetUnrestrictedText(box);
var allowedChars = GetRestrictDeleteTo(box);
if(box.Text==oldText || allowdChars==null) return;
foreach(var change in changeEvent.Changes)
if(change.RemovedLength>0)
{
string deleted = box.Text.Substring(change.Offset, change.RemovedLength);
if(deleted.Any(ch => !allowedChars.Contains(ch)))
box.Text = oldText;
}
SetUnrestrictedText(box, box.Text);
};
}
});
// UnrestrictedText: Bind or access this property to update the Text property bypassing all restrictions
public static string GetUnrestrictedText(DependencyObject obj) { return (string)obj.GetValue(UnrestrictedTextProperty); }
public static void SetUnrestrictedText(DependencyObject obj, string value) { obj.SetValue(UnrestrictedTextProperty, value); }
public static readonly DependencyProperty UnrestrictedTextProperty = DependencyProperty.RegisterAttached("UnrestrictedText", typeof(string), typeof(TextBoxRestriction), new PropertyMetadata
{
DefaultValue = "",
PropertyChangedCallback = (obj, e) =>
{
var box = (TextBox)obj;
box.Text = (string)e.NewValue;
}
});
}
Comment ça marche: Lorsque vous définissez UnrestrictedText il définit texte et vice versa. Le gestionnaire TextChanged vérifie si Text est différent de UnrestrictedText. Si tel est le cas, il sait que le texte a été mis à jour par un autre mécanisme que la définition de UnrestrictedText de sorte qu'il analyse les modifications pour une suppression illégale. Si l'un d'eux est trouvé, il rétablit Text à la valeur encore stockée dans UnrestrictedText, empêchant la modification.
Aide énorme! Je l'ai légèrement modifié pour éviter la suppression du dernier caractère qu'un utilisateur tente de supprimer. – alan