2009-07-09 19 views
52

Come posso limitare TextBox ad accettare solo lettere maiuscole o, ad esempio, cifre o vietare di inserire caratteri speciali?Come definire le restrizioni di input per TextBox?

Certo che è un pezzo di torta per catturare l'evento TextInput e gestire il testo qui, ma è il modo corretto per farlo?

risposta

110

Ho fatto questo in passato con un comportamento annesso, che può essere utilizzato in questo modo:

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

Il codice di comportamento in allegato si presenta così:

/// <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 .. merda .. perché è così difficile? – Agzam

+0

Non direi che lo fosse. L'ho scritto per essere molto più flessibile del necessario. Sentiti libero di prendere il concetto e semplificare per le tue esigenze. –

+1

Molto bello, Kent. Una soluzione flessibile e potente per limitare l'ingresso in 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

Non so come renderlo una proprietà personalizzata, ma è una soluzione semplice. Sarei grato se qualcuno lo convertisse in proprietà come ha fatto Kent. – WhoIsNinja

43

I Ho migliorato la risposta di Kent Boogaart gestendo anche le seguenti azioni che in precedenza potevano causare la violazione del modello:

  • Backspace
  • Selezione e il testo trascinando in un modo che può violare il modello
  • comando Taglia

Per esempio, la risposta di Kent Boogaart permesso all'utente di inserire "ac" immettendo prima "abc" e poi eliminare il "b" con il backspace che viola la seguente espressione regolare

^(a|ab|abc)$ 

Usage (invariato):

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

classe Mask:

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

Hai migliorato la soluzione in 3 modi, ma leggendo la sua breve descrizione non suona un campanello. Penso che abbia a che fare con la copia del testo incollato nel TextBox ma la soluzione di Kent ha già bloccato il testo difettoso. Puoi forse spiegare quali sono i casi d'uso che i miglioramenti impediscono? Grazie – buckley

+0

Questi miglioramenti impediscono all'utente di violare la regola regex. Ad esempio, prima di queste modifiche, è possibile utilizzare Backspace per rendere illegale la regola. Quindi se il pattern era '^ 123 $' potevi digitare '123' e poi cancellare' 2' e ti avrebbe permesso. Adesso no. Lo stesso vale per gli altri miglioramenti: tagliare il testo e trascinare il testo. – VitalyB

+0

Posso vedere cosa intendi ora, ma solo un'azione di copia incolla può portare l'utente al punto in cui c'è "123" nella casella di testo per iniziare. Digitare solo il carattere "1" (o qualsiasi altro carattere) sarà impossibile in quanto non convalida "^ 123 $". L'uso di backspace su un * digitato * nella stringa rispetta sempre il modello poiché l'input precedente era già stato convalidato. Alcuni utenti sicuramente copieranno pasta e il tuo miglioramento affronterà questo caso limite che sarebbe stato un mistero per un po 'come è successo. Grazie – buckley

12

ho cambiato il codice di VitalyB per sostenere Temi colore. Invece di bloccare l'input dell'utente se non soddisfa lo script RegEx, evidenzia semplicemente la casella di testo. La casella di testo sarà l'impostazione predefinita del tema senza interazione, quindi verrà automaticamente impostata su una luce verde o rossa a seconda del valore dopo l'impostazione dell'ingresso. È anche possibile impostare la falliscono e passano i colori programatically con:

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

La classe è qui sotto:

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

a correre, lo script richiede una classe scritta da Aaron C, ha spiegato qui: Silverlight/WPF sets ellipse with hexadecimal colour mostrato qui : http://www.wiredprairie.us/blog/index.php/archives/659

il codice è inferiore nel caso in cui il sito è mai mosso:

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

} 
Problemi correlati