2009-07-09 28 views
52

Làm cách nào để hạn chế TextBox chỉ chấp nhận chữ cái viết hoa, hoặc ví dụ như chữ số, hoặc cấm đặt bất kỳ ký tự đặc biệt nào?Làm cách nào để xác định giới hạn nhập của TextBox?

Chắc chắn đó là một miếng bánh để nắm bắt sự kiện TextInput và xử lý văn bản ở đây, nhưng đó có phải là cách thích hợp để thực hiện việc này không?

Trả lời

110

Tôi đã làm điều này trong quá khứ với một hành vi gắn liền, có thể được sử dụng như thế này:

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

Mã hành vi được đính kèm giống như thế này:

/// <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 .. đi tiêu .. tại sao nó là rất khó khăn? – Agzam

+0

Tôi sẽ không nói đó là. Tôi đã viết nó linh hoạt hơn bạn cần. Cảm thấy tự do chỉ cần lấy khái niệm và đơn giản hóa cho nhu cầu của bạn. –

+1

Rất đẹp, Kent. Một giải pháp linh hoạt và mạnh mẽ để hạn chế mục nhập trong một 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

Tôi không biết làm thế nào để làm cho nó một tài sản tùy chỉnh, nhưng nó là một giải pháp đơn giản. Tôi sẽ đánh giá cao nếu có ai chuyển đổi nó thành tài sản giống như Kent đã làm. – WhoIsNinja

43

tôi đã cải thiện câu trả lời của Kent Boogaart bằng cách xử lý các hành động sau đây trước đây có thể khiến mẫu bị vi phạm:

  • Backspace
  • Lựa chọn và kéo văn bản trong một cách mà có thể vi phạm các mẫu
  • Cut lệnh

Ví dụ, câu trả lời Kent Boogaart của phép người dùng nhập "ac" bằng cách đầu tiên nhập "abc" và sau đó xóa các "b" với phím lùi vi phạm các regex

^(a|ab|abc)$ 

Cách sử dụng như sau (không thay đổi):

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

Mask lớp:

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

Bạn đã cải thiện giải pháp theo 3 cách nhưng đọc mô tả ngắn của nó không đổ chuông. Tôi nghĩ rằng nó đã làm với sao chép văn bản dán trong TextBox nhưng giải pháp của Kent đã bị chặn văn bản bị lỗi. Bạn có thể giải thích những trường hợp sử dụng nào mà cải tiến ngăn chặn không? Cảm ơn bạn – buckley

+0

Những cải tiến này ngăn người dùng vi phạm quy tắc regex. Vì vậy, ví dụ, trước những thay đổi này, bạn có thể sử dụng Backspace để làm cho các quy tắc bất hợp pháp. Vì vậy, nếu mẫu là '^ 123 $' bạn có thể gõ '123' và sau đó xóa' 2' và nó sẽ cho phép bạn. Bây giờ nó không. Tương tự cho những cải tiến khác - Cắt văn bản và kéo văn bản xung quanh. – VitalyB

+0

Tôi có thể thấy ý của bạn bây giờ nhưng chỉ một thao tác sao chép có thể đưa người dùng đến điểm có "123" trong hộp văn bản để bắt đầu. Chỉ nhập ký tự "1" (hoặc bất kỳ ký tự nào khác) sẽ không thể vì nó không xác thực "^ 123 $". Sử dụng backspace trên một * typed * in chuỗi sẽ luôn luôn tôn trọng các mô hình như đầu vào trước đó đã được xác nhận. Một số người dùng chắc chắn sẽ sao chép dán và cải thiện của bạn sẽ giải quyết trường hợp cạnh này mà có thể là một bí ẩn trong một thời gian như thế nào nó xảy ra. Cảm ơn – buckley

12

tôi thay đổi mã VitalyB để hỗ trợ Màu Chủ đề. Thay vì chặn đầu vào của người dùng nếu nó không đáp ứng được kịch bản RegEx, nó chỉ làm nổi bật hộp văn bản. Hộp văn bản sẽ là mặc định chủ đề không có tương tác, và sau đó mặc định là màu xanh lá cây nhạt hoặc đỏ tùy thuộc vào giá trị sau khi đầu vào được đặt. Bạn cũng có thể thiết lập các thất bại và vượt qua màu sắc programatically với:

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

Lớp dưới:

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

Để chạy, kịch bản đòi hỏi một lớp được viết bởi Aaron C, giải thích ở đây: Silverlight/WPF sets ellipse with hexadecimal colour đưa ra ở đây : http://www.wiredprairie.us/blog/index.php/archives/659

mã dưới trong trường hợp trang web được bao giờ di chuyển:

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

} 
Các vấn đề liên quan