Как реализовать свойство TextChanging для TextBox? - PullRequest
0 голосов
/ 07 февраля 2012

Я подумал, что уже будет такой вопрос, но мне не повезло в поисках.Я видел вопрос, где кто-то спросил то же самое, но ответом было использование события TextChanged.Это не то, чего я хочу.

TextBox имеет событие для TextChanged, которое происходит после изменения свойства Text.Мне нужно, чтобы мой элемент управления вызвал событие до того, как свойство Text будет фактически изменено для проверки данных.Если он действителен, текст может быть изменен, если он недействителен, текст не изменяется.

Вот что я пробовал:

Public Class TextChangingEventArgs
  Inherits System.ComponentModel.CancelEventArgs

  Private p_sNewValue As String 

  Public Sub New()
    p_sNewValue = String.Empty
  End Sub

  Public Sub New(sNewValue As String)
    p_sNewValue = sNewValue
  End Sub

  Public Property NewValue As String
    Get
      Return p_sNewValue
    End Get
    Set(value As String)
      p_sNewValue = value
    End Set
  End Property
End Class

Public Class BetterTextBox
  Inherits TextBox

  Public Event TextChanging(sender As Object, e As TextChangingEventArgs)

  Public Overrides Property Text As String
    Get
      Return MyBase.Text
    End Get
    Set(value As String)
      Dim e As New TextChangingEventArgs(value)
      RaiseEvent TextChanging(Me, e)
      If e.Cancel = False Then
        MyBase.Text = value
      End If
    End Set
  End Property 
End Class

Мой в моей форме я обрабатываю TextChangingevent:

Private Sub BetterTextBox1_TextChanging(sender As System.Object, e As TextChangingEventArgs) Handles BetterTextBox1.TextChanging
  e.Cancel = Not Regex.IsMatch(e.NewValue, REGEX_PATTERN)
End Sub

Это работает для программной установки значения Text элемента управления BetterTextBox, но не работает при вводе текста в текстовом поле.

Кто-нибудь знает, что мне нужносделать, чтобы заставить это работать?

Ответы [ 4 ]

2 голосов
/ 07 февраля 2012

Поскольку вы уже наследуете от TextBox, вы можете переопределить WndProc и проверить наличие сообщений для вставки.Это должно решить правой кнопкой мыши> Вставить проблему.Затем вы можете обрабатывать «обычный» набранный текст в KeyPressed или KeyDown, как предлагали другие.Вот пример того, о чем я говорю:

Private Const WM_PASTE As Integer = &H302
Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_PASTE AndAlso Clipboard.ContainsText() AndAlso ShouldAllowPaste(Clipboard.GetText()) Then
        MyBase.WndProc(m)
    ElseIf m.Msg <> WM_PASTE Then
        MyBase.WndProc(m)
    End If
End Sub
1 голос
/ 07 февраля 2012

Попробуйте это:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If m.Msg = 8465 Then
        If HIWORD(m.WParam) = 1024 Then
            ' raise your TextChanging event
        End If
    End If

    MyBase.WndProc(m)
End Sub

Public Function HIWORD(ByVal n As Integer) As UInteger
    Return CUInt(n >> 16) And CUInt(&HFFFF)
End Function
0 голосов
/ 07 февраля 2012

Я бы посоветовал вам попробовать с событием keydown. Это происходит до текстового обмена или даже до нажатие клавиши.

0 голосов
/ 07 февраля 2012

Вместо этого попробуйте событие KeyPress в текстовом поле.

РЕДАКТИРОВАТЬ : чтобы отключить щелчок правой кнопкой мыши в текстовом поле, вы можете сделать что-то подобное.Поместите этот код в событие MouseDown Textbox.

If e.Button = MouseButtons.Right Then
    MessageBox.Show("can't paste!")
    Exit Sub
End If

, однако я заметил, что вы все равно можете вставить текст, используя комбинацию клавиш Ctrl + V. Вы можете написать этот код, чтобы остановить его в событии KeyPress.

If Keys.ControlKey And Keys.V Then
       MessageBox.Show("can't paste!")
       Exit Sub
End If
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...