2011-10-14 25 views
0

在我的WPF文本框我已經驗證了它在下列事件如何驗證WPF中剪貼板中的字符串?

框TextChanged PreviewTextInput

,使用戶不能容許它特殊字符,但用戶能夠要麼通過Ctrl + V鍵或粘貼特殊字符通過鼠標右鍵單擊並粘貼。

如何在文本框上驗證這兩個額外的事件。

+1

看看http://stackoverflow.com/questions/1103765/wpf-textbox-how-to-define-some-restriction –

+0

丹尼爾你的鏈接幫助我最:)謝謝很多 – Abhi

回答

0

XAML:

<TextBox b:Masking.Mask="someregularExpressionhere"/> 

後面的代碼:

/// <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; 
      } 
    } 
+0

什麼樣的名字空間是'b'? – Nickon

1

剪貼板服務支持PastingHandlers

 DataObject.AddPastingHandler(textBox, OnPaste); 

在處理程序取消處理程序無效數據....我認爲它有e.CancelCommand()電話。

1

您可以通過使用DataObjectPastingEventArgs寫粘貼情況,請this控制粘貼

private void OnPasting(object sender, DataObjectPastingEventArgs e) 
{  
var isText = e.SourceDataObject.GetDataPresent(System.Windows.DataFormats.Text, true); 
if (!isText) 
return; 
    var text = e.SourceDataObject.GetData(DataFormats.Text) as string;  

} 
1

最好的辦法是描述爲this question的答案(SO轉換了我以前的回答呃發表評論,但那些不能被接受)。

相關問題