2009-07-09 19 views
52

¿Cómo puedo restringir que TextBox acepte solamente letras mayúsculas, o por ejemplo dígitos, o prohíba poner cualquier carácter especial?¿Cómo se definen las restricciones de entrada de TextBox?

Seguro que es un pedazo de pastel detectar el evento TextInput y manejar el texto aquí, pero ¿es la forma correcta de hacerlo?

Respuesta

110

que he hecho esto en el pasado con un comportamiento adjunto, que puede ser utilizado como esto:

<TextBox b:Masking.Mask="^\p{Lu}*$"/> 

El código de comportamiento adjunto es el siguiente:

/// <summary> 
/// Provides masking behavior for any <see cref="TextBox"/>. 
/// </summary> 
public static class Masking 
{ 
    private static readonly DependencyPropertyKey _maskExpressionPropertyKey = DependencyProperty.RegisterAttachedReadOnly("MaskExpression", 
     typeof(Regex), 
     typeof(Masking), 
     new FrameworkPropertyMetadata()); 

    /// <summary> 
    /// Identifies the <see cref="Mask"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty MaskProperty = DependencyProperty.RegisterAttached("Mask", 
     typeof(string), 
     typeof(Masking), 
     new FrameworkPropertyMetadata(OnMaskChanged)); 

    /// <summary> 
    /// Identifies the <see cref="MaskExpression"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty MaskExpressionProperty = _maskExpressionPropertyKey.DependencyProperty; 

    /// <summary> 
    /// Gets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask, or <see langword="null"/> if no mask has been set. 
    /// </returns> 
    public static string GetMask(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskProperty) as string; 
    } 

    /// <summary> 
    /// Sets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be set. 
    /// </param> 
    /// <param name="mask"> 
    /// The mask to set, or <see langword="null"/> to remove any existing mask from <paramref name="textBox"/>. 
    /// </param> 
    public static void SetMask(TextBox textBox, string mask) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     textBox.SetValue(MaskProperty, mask); 
    } 

    /// <summary> 
    /// Gets the mask expression for the <see cref="TextBox"/>. 
    /// </summary> 
    /// <remarks> 
    /// This method can be used to retrieve the actual <see cref="Regex"/> instance created as a result of setting the mask on a <see cref="TextBox"/>. 
    /// </remarks> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask expression is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask expression as an instance of <see cref="Regex"/>, or <see langword="null"/> if no mask has been applied to <paramref name="textBox"/>. 
    /// </returns> 
    public static Regex GetMaskExpression(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskExpressionProperty) as Regex; 
    } 

    private static void SetMaskExpression(TextBox textBox, Regex regex) 
    { 
     textBox.SetValue(_maskExpressionPropertyKey, regex); 
    } 

    private static void OnMaskChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var textBox = dependencyObject as TextBox; 
     var mask = e.NewValue as string; 
     textBox.PreviewTextInput -= textBox_PreviewTextInput; 
     textBox.PreviewKeyDown -= textBox_PreviewKeyDown; 
     DataObject.RemovePastingHandler(textBox, Pasting); 

     if (mask == null) 
     { 
      textBox.ClearValue(MaskProperty); 
      textBox.ClearValue(MaskExpressionProperty); 
     } 
     else 
     { 
      textBox.SetValue(MaskProperty, mask); 
      SetMaskExpression(textBox, new Regex(mask, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace)); 
      textBox.PreviewTextInput += textBox_PreviewTextInput; 
      textBox.PreviewKeyDown += textBox_PreviewKeyDown; 
      DataObject.AddPastingHandler(textBox, Pasting); 
     } 
    } 

    private static void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     var proposedText = GetProposedText(textBox, e.Text); 

     if (!maskExpression.IsMatch(proposedText)) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void textBox_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     //pressing space doesn't raise PreviewTextInput - no idea why, but we need to handle 
     //explicitly here 
     if (e.Key == Key.Space) 
     { 
      var proposedText = GetProposedText(textBox, " "); 

      if (!maskExpression.IsMatch(proposedText)) 
      { 
       e.Handled = true; 
      } 
     } 
    } 

    private static void Pasting(object sender, DataObjectPastingEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     if (e.DataObject.GetDataPresent(typeof(string))) 
     { 
      var pastedText = e.DataObject.GetData(typeof(string)) as string; 
      var proposedText = GetProposedText(textBox, pastedText); 

      if (!maskExpression.IsMatch(proposedText)) 
      { 
       e.CancelCommand(); 
      } 
     } 
     else 
     { 
      e.CancelCommand(); 
     } 
    } 

    private static string GetProposedText(TextBox textBox, string newText) 
    { 
     var text = textBox.Text; 

     if (textBox.SelectionStart != -1) 
     { 
      text = text.Remove(textBox.SelectionStart, textBox.SelectionLength); 
     } 

     text = text.Insert(textBox.CaretIndex, newText); 

     return text; 
    } 
} 
+27

Wow .. mierda .. por qué es tan difícil? – Agzam

+0

No diría que fue. Lo escribí para ser mucho más flexible de lo que necesita. Siéntase libre de simplemente tomar el concepto y simplificarlo para sus necesidades. –

+1

Muy agradable, Kent. Una solución flexible y poderosa para limitar la entrada en un TextBox. +1 –

2
private void TextBox1_SelectionChanged(object sender, RoutedEventArgs e) 
{ 
    string txt = TextBox1.Text; 
    if (txt != "") 
    { 
     TextBox1.Text = Regex.Replace(TextBox1.Text, "[^0-9]", ""); 
     if (txt != TextBox1.Text) 
     { 
      TextBox1.Select(TextBox1.Text.Length, 0); 
     } 
    } 
} 
+0

No sé cómo convertirlo en una propiedad personalizada, pero es una solución simple. Agradecería que alguien lo convirtiera en propiedad como lo hizo Kent. – WhoIsNinja

43

I Ha mejorado la respuesta de Kent Boogaart al manejar también las siguientes acciones que anteriormente podían causar la violación del patrón:

  • Retroceso
  • Selección y texto arrastrando de una manera que puede violar el patrón
  • comando Cortar

Por ejemplo, la respuesta de Kent Boogaart permitió que el usuario introduzca "ac" mediante la introducción de primera "abc" y después eliminar la "b" con la tecla de retroceso que viola la siguiente expresión regular

^(a|ab|abc)$ 

uso (sin cambios):

<TextBox b:Masking.Mask="^\p{Lu}*$"/>

clase Máscara:

public static class Masking 
{ 
    private static readonly DependencyPropertyKey _maskExpressionPropertyKey = DependencyProperty.RegisterAttachedReadOnly("MaskExpression", 
      typeof(Regex), 
      typeof(Masking), 
      new FrameworkPropertyMetadata()); 

    /// <summary> 
    /// Identifies the <see cref="Mask"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty MaskProperty = DependencyProperty.RegisterAttached("Mask", 
      typeof(string), 
      typeof(Masking), 
      new FrameworkPropertyMetadata(OnMaskChanged)); 

    /// <summary> 
    /// Identifies the <see cref="MaskExpression"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty MaskExpressionProperty = _maskExpressionPropertyKey.DependencyProperty; 

    /// <summary> 
    /// Gets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask, or <see langword="null"/> if no mask has been set. 
    /// </returns> 
    public static string GetMask(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskProperty) as string; 
    } 

    /// <summary> 
    /// Sets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be set. 
    /// </param> 
    /// <param name="mask"> 
    /// The mask to set, or <see langword="null"/> to remove any existing mask from <paramref name="textBox"/>. 
    /// </param> 
    public static void SetMask(TextBox textBox, string mask) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     textBox.SetValue(MaskProperty, mask); 
    } 

    /// <summary> 
    /// Gets the mask expression for the <see cref="TextBox"/>. 
    /// </summary> 
    /// <remarks> 
    /// This method can be used to retrieve the actual <see cref="Regex"/> instance created as a result of setting the mask on a <see cref="TextBox"/>. 
    /// </remarks> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask expression is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask expression as an instance of <see cref="Regex"/>, or <see langword="null"/> if no mask has been applied to <paramref name="textBox"/>. 
    /// </returns> 
    public static Regex GetMaskExpression(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskExpressionProperty) as Regex; 
    } 

    private static void SetMaskExpression(TextBox textBox, Regex regex) 
    { 
     textBox.SetValue(_maskExpressionPropertyKey, regex); 
    } 

    private static void OnMaskChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var textBox = dependencyObject as TextBox; 
     var mask = e.NewValue as string; 
     textBox.PreviewTextInput -= textBox_PreviewTextInput; 
     textBox.PreviewKeyDown -= textBox_PreviewKeyDown; 
     DataObject.RemovePastingHandler(textBox, Pasting); 
     DataObject.RemoveCopyingHandler(textBox, NoDragCopy); 
     CommandManager.RemovePreviewExecutedHandler(textBox, NoCutting); 


     if (mask == null) 
     { 
      textBox.ClearValue(MaskProperty); 
      textBox.ClearValue(MaskExpressionProperty); 
     } 
     else 
     { 
      textBox.SetValue(MaskProperty, mask); 
      SetMaskExpression(textBox, new Regex(mask, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace)); 
      textBox.PreviewTextInput += textBox_PreviewTextInput; 
      textBox.PreviewKeyDown += textBox_PreviewKeyDown; 
      DataObject.AddPastingHandler(textBox, Pasting); 
      DataObject.AddCopyingHandler(textBox, NoDragCopy); 
      CommandManager.AddPreviewExecutedHandler(textBox, NoCutting); 
     } 
    } 

    private static void NoCutting(object sender, ExecutedRoutedEventArgs e) 
    { 
     if(e.Command == ApplicationCommands.Cut) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void NoDragCopy(object sender, DataObjectCopyingEventArgs e) 
    { 
     if (e.IsDragDrop) 
     { 
      e.CancelCommand(); 
     } 
    } 

    private static void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     var proposedText = GetProposedText(textBox, e.Text); 

     if (!maskExpression.IsMatch(proposedText)) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void textBox_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     string proposedText = null; 

     //pressing space doesn't raise PreviewTextInput, reasons here http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b?prof=required 
     if (e.Key == Key.Space) 
     { 
      proposedText = GetProposedText(textBox, " "); 
     } 
     // Same story with backspace 
     else if(e.Key == Key.Back) 
     { 
      proposedText = GetProposedTextBackspace(textBox); 
     } 

     if (proposedText != null && proposedText != string.Empty && !maskExpression.IsMatch(proposedText)) 
     { 
      e.Handled = true; 
     } 

    } 

    private static void Pasting(object sender, DataObjectPastingEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     if (e.DataObject.GetDataPresent(typeof(string))) 
     { 
      var pastedText = e.DataObject.GetData(typeof(string)) as string; 
      var proposedText = GetProposedText(textBox, pastedText); 

      if (!maskExpression.IsMatch(proposedText)) 
      { 
       e.CancelCommand(); 
      } 
     } 
     else 
     { 
      e.CancelCommand(); 
     } 
    } 

    private static string GetProposedTextBackspace(TextBox textBox) 
    { 
     var text = GetTextWithSelectionRemoved(textBox); 
     if (textBox.SelectionStart > 0 && textBox.SelectionLength == 0) 
     { 
      text = text.Remove(textBox.SelectionStart-1, 1); 
     } 

     return text; 
    } 


    private static string GetProposedText(TextBox textBox, string newText) 
    { 
     var text = GetTextWithSelectionRemoved(textBox); 
     text = text.Insert(textBox.CaretIndex, newText); 

     return text; 
    } 

    private static string GetTextWithSelectionRemoved(TextBox textBox) 
    { 
     var text = textBox.Text; 

     if (textBox.SelectionStart != -1) 
     { 
      text = text.Remove(textBox.SelectionStart, textBox.SelectionLength); 
     } 
     return text; 
    } 
} 
+0

Ha mejorado la solución de 3 maneras, pero leer su breve descripción no suena. Creo que tiene que ver con copiar texto pegado en el TextBox pero la solución de Kent ya bloqueó el texto defectuoso. ¿Puede explicarnos qué casos de uso previenen las mejoras? Gracias – buckley

+0

Estas mejoras evitan que el usuario viole la regla de expresiones regulares. Entonces, por ejemplo, antes de estos cambios, puede usar Retroceso para hacer que la regla sea ilegal. Entonces, si el patrón fuera '^ 123 $', podría escribir '123' y luego eliminar' 2' y le dejaría. Ahora no. Lo mismo ocurre con las otras mejoras: cortar texto y arrastrar texto. – VitalyB

+0

Puedo ver lo que quiere decir ahora, pero solo una acción de copiar y pegar puede llevar al usuario al punto donde hay "123" en el cuadro de texto para comenzar. Escribir simplemente el carácter "1" (o cualquier otro carácter) será imposible ya que no valida "^ 123 $". El uso de retroceso en una cadena * tipada * siempre respetará el patrón ya que la entrada anterior ya estaba validada. Algunos usuarios definitivamente copiarán pegar y su mejora abordará este caso extremo que hubiera sido un misterio por un tiempo cómo sucedió. Gracias – buckley

12

me cambió el código de VitalyB para apoyar temas de color. En lugar de bloquear la entrada del usuario si no cumple con la secuencia de comandos RegEx, solo resalta el cuadro de texto. El cuadro de texto será el tema predeterminado sin interacción, y luego se cambiará a verde claro o rojo dependiendo del valor una vez que se establezca la entrada. También puede establecer la falla y pasan colores mediante programación con:

b:ColorMasking.PassColor = "Hexadecimal Value" 
b:ColorMasking.FailColor = "Hexadecimal Value" 

La clase es el siguiente:

public class ColorMasking : DependencyObject 
{ 
    private static readonly DependencyPropertyKey _maskExpressionPropertyKey = DependencyProperty.RegisterAttachedReadOnly("MaskExpression", 
      typeof(Regex), 
      typeof(ColorMasking), 
      new FrameworkPropertyMetadata()); 

    /// <summary> 
    /// Identifies the <see cref="Mask"/> dependency property. 
    /// </summary> 
    /// 
    public static readonly DependencyProperty PassColorProperty = DependencyProperty.RegisterAttached("PassColor", 
      typeof(string), 
      typeof(ColorMasking), 
      new PropertyMetadata("#99FF99")); 

    public static void SetPassColor(DependencyObject obj, string passColor) 
    { 
     obj.SetValue(PassColorProperty, passColor); 
    } 

    public static string GetPassColor(DependencyObject obj) 
    { 
     return (string)obj.GetValue(PassColorProperty); 
    } 


    public static readonly DependencyProperty FailColorProperty = DependencyProperty.RegisterAttached("FailColor", 
      typeof(string), 
      typeof(ColorMasking), 
      new PropertyMetadata("#FFCCFF")); 

    public static void SetFailColor(DependencyObject obj, string failColor) 
    { 
     obj.SetValue(FailColorProperty, failColor); 
    } 

    public static string GetFailColor(DependencyObject obj) 
    { 
     return (string)obj.GetValue(FailColorProperty); 
    } 

    public static readonly DependencyProperty MaskProperty = DependencyProperty.RegisterAttached("Mask", 
      typeof(string), 
      typeof(ColorMasking), 
      new FrameworkPropertyMetadata(OnMaskChanged)); 

    private static void OnPassColorChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var textBox = dependencyObject as TextBox; 
     var color = e.NewValue as string; 
     textBox.SetValue(PassColorProperty, color); 
    } 

    /// <summary> 
    /// Identifies the <see cref="MaskExpression"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty MaskExpressionProperty = _maskExpressionPropertyKey.DependencyProperty; 

    /// <summary> 
    /// Gets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask, or <see langword="null"/> if no mask has been set. 
    /// </returns> 
    public static string GetMask(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskProperty) as string; 
    } 

    /// <summary> 
    /// Sets the mask for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask is to be set. 
    /// </param> 
    /// <param name="mask"> 
    /// The mask to set, or <see langword="null"/> to remove any existing mask from <paramref name="textBox"/>. 
    /// </param> 
    public static void SetMask(TextBox textBox, string mask) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     textBox.SetValue(MaskProperty, mask); 
    } 

    /// <summary> 
    /// Gets the mask expression for the <see cref="TextBox"/>. 
    /// </summary> 
    /// <remarks> 
    /// This method can be used to retrieve the actual <see cref="Regex"/> instance created as a result of setting the mask on a <see cref="TextBox"/>. 
    /// </remarks> 
    /// <param name="textBox"> 
    /// The <see cref="TextBox"/> whose mask expression is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The mask expression as an instance of <see cref="Regex"/>, or <see langword="null"/> if no mask has been applied to <paramref name="textBox"/>. 
    /// </returns> 
    public static Regex GetMaskExpression(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return textBox.GetValue(MaskExpressionProperty) as Regex; 
    } 

    private static void SetMaskExpression(TextBox textBox, Regex regex) 
    { 
     textBox.SetValue(_maskExpressionPropertyKey, regex); 
    } 

    private static void OnMaskChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var textBox = dependencyObject as TextBox; 
     var mask = e.NewValue as string; 
     textBox.PreviewTextInput -= textBox_PreviewTextInput; 
     textBox.PreviewKeyDown -= textBox_PreviewKeyDown; 
     DataObject.RemovePastingHandler(textBox, Pasting); 
     DataObject.RemoveCopyingHandler(textBox, NoDragCopy); 
     CommandManager.RemovePreviewExecutedHandler(textBox, NoCutting); 

     if (mask == null) 
     { 
      textBox.ClearValue(MaskProperty); 
      textBox.ClearValue(MaskExpressionProperty); 
     } 
     else 
     { 
      textBox.SetValue(MaskProperty, mask); 
      SetMaskExpression(textBox, new Regex(mask, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace)); 
      textBox.PreviewTextInput += textBox_PreviewTextInput; 
      textBox.PreviewKeyDown += textBox_PreviewKeyDown; 
      DataObject.AddPastingHandler(textBox, Pasting); 
      DataObject.AddCopyingHandler(textBox, NoDragCopy); 
      CommandManager.AddPreviewExecutedHandler(textBox, NoCutting); 
     } 
    } 

    private static void NoCutting(object sender, ExecutedRoutedEventArgs e) 
    { 
     if (e.Command == ApplicationCommands.Cut) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void NoDragCopy(object sender, DataObjectCopyingEventArgs e) 
    { 
     if (e.IsDragDrop) 
     { 
      e.CancelCommand(); 
     } 
    } 

    private static void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     string passHex = (string)textBox.GetValue(PassColorProperty); 
     string failHex = (string)textBox.GetValue(FailColorProperty); 
     Color passColor = Extensions.ToColorFromHex(passHex); 
     Color failColor = Extensions.ToColorFromHex(failHex); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     var proposedText = GetProposedText(textBox, e.Text); 

     if (!maskExpression.IsMatch(proposedText)) 
     { 
      textBox.Background = new SolidColorBrush(failColor); 
     } 
     else 
     { 
      textBox.Background = new SolidColorBrush(passColor); 
     } 
    } 

    private static void textBox_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     string passHex = (string)textBox.GetValue(PassColorProperty); 
     string failHex = (string)textBox.GetValue(FailColorProperty); 
     Color passColor = Extensions.ToColorFromHex(passHex); 
     Color failColor = Extensions.ToColorFromHex(failHex); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     string proposedText = null; 

     //pressing space doesn't raise PreviewTextInput, reasons here http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b?prof=required 
     if (e.Key == Key.Space) 
     { 
      proposedText = GetProposedText(textBox, " "); 
     } 
     // Same story with backspace 
     else if (e.Key == Key.Back) 
     { 
      proposedText = GetProposedTextBackspace(textBox); 
     } 

     if (proposedText != null && !maskExpression.IsMatch(proposedText)) 
     { 
      textBox.Background = new SolidColorBrush(failColor); 
     } 
     else 
     { 
      textBox.Background = new SolidColorBrush(passColor); 
     } 

    } 

    private static void Pasting(object sender, DataObjectPastingEventArgs e) 
    { 
     TextBox textBox = sender as TextBox; 
     var maskExpression = GetMaskExpression(textBox); 

     string passHex = (string)textBox.GetValue(PassColorProperty); 
     string failHex = (string)textBox.GetValue(FailColorProperty); 
     Color passColor = Extensions.ToColorFromHex(passHex); 
     Color failColor = Extensions.ToColorFromHex(failHex); 

     if (maskExpression == null) 
     { 
      return; 
     } 

     if (e.DataObject.GetDataPresent(typeof(string))) 
     { 
      var pastedText = e.DataObject.GetData(typeof(string)) as string; 
      var proposedText = GetProposedText(textBox, pastedText); 

      if (!maskExpression.IsMatch(proposedText)) 
      { 
       textBox.Background = new SolidColorBrush(failColor); 
      } 
      else 
      { 
       textBox.Background = new SolidColorBrush(passColor); 
      } 
     } 
     else 
     { 
      textBox.Background = new SolidColorBrush(failColor); 
     } 
    } 

    private static string GetProposedTextBackspace(TextBox textBox) 
    { 
     var text = GetTextWithSelectionRemoved(textBox); 
     if (textBox.SelectionStart > 0) 
     { 
      text = text.Remove(textBox.SelectionStart - 1, 1); 
     } 

     return text; 
    } 


    private static string GetProposedText(TextBox textBox, string newText) 
    { 
     var text = GetTextWithSelectionRemoved(textBox); 
     text = text.Insert(textBox.CaretIndex, newText); 

     return text; 
    } 

    private static string GetTextWithSelectionRemoved(TextBox textBox) 
    { 
     var text = textBox.Text; 

     if (textBox.SelectionStart != -1) 
     { 
      text = text.Remove(textBox.SelectionStart, textBox.SelectionLength); 
     } 
     return text; 
    } 
} 

para correr, el guión requiere una clase escrita por Aaron C, que se explica aquí: Silverlight/WPF sets ellipse with hexadecimal colour muestran aquí : http://www.wiredprairie.us/blog/index.php/archives/659

el código está por debajo en caso de que el sitio web es movida:

public static class Extensions 
{ 
    public static void SetFromHex(this Color c, string hex) 
    { 
     Color c1 = ToColorFromHex(hex); 

     c.A = c1.A; 
     c.R = c1.R; 
     c.G = c1.G; 
     c.B = c1.B; 
    } 

    public static Color ToColorFromHex(string hex) 
    { 
     if (string.IsNullOrEmpty(hex)) 
     { 
      throw new ArgumentNullException("hex"); 
     } 

     // remove any "#" characters 
     while (hex.StartsWith("#")) 
     { 
      hex = hex.Substring(1); 
     } 

     int num = 0; 
     // get the number out of the string 
     if (!Int32.TryParse(hex, System.Globalization.NumberStyles.HexNumber, null, out num)) 
     { 
      throw new ArgumentException("Color not in a recognized Hex format."); 
     } 

     int[] pieces = new int[4]; 
     if (hex.Length > 7) 
     { 
      pieces[0] = ((num >> 24) & 0x000000ff); 
      pieces[1] = ((num >> 16) & 0x000000ff); 
      pieces[2] = ((num >> 8) & 0x000000ff); 
      pieces[3] = (num & 0x000000ff); 
     } 
     else if (hex.Length > 5) 
     { 
      pieces[0] = 255; 
      pieces[1] = ((num >> 16) & 0x000000ff); 
      pieces[2] = ((num >> 8) & 0x000000ff); 
      pieces[3] = (num & 0x000000ff); 
     } 
     else if (hex.Length == 3) 
     { 
      pieces[0] = 255; 
      pieces[1] = ((num >> 8) & 0x0000000f); 
      pieces[1] += pieces[1] * 16; 
      pieces[2] = ((num >> 4) & 0x000000f); 
      pieces[2] += pieces[2] * 16; 
      pieces[3] = (num & 0x000000f); 
      pieces[3] += pieces[3] * 16; 
     } 
     return Color.FromArgb((byte)pieces[0], (byte)pieces[1], (byte)pieces[2], (byte)pieces[3]); 
    } 

} 
Cuestiones relacionadas