TextBox.SelStart дает различное значение для мыши и клавиатуры - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть TextBox на Form.Я беру позицию курсора , используя .SelStart свойство в этом TextBox.Это работает как требуется, когда я нажимаю в пределах TextBox.Затем я использую эту позицию для вставки определенных символов в положение курсора , нажимая кнопки в той же форме, которые печатают их подписи .

Однако, если я наберу некоторые символы с клавиатуры в TextBox, Selstart вернет 0. Даже если я наберу несколько символов и курсор явнов конце текста SelStart остается 0. Теперь, если я печатаю кнопки на другой форме , новые символы печатаются всегда в начале TextBox, что не являетсяЯ хочу.Я хочу, чтобы подписи печатались всегда в курсоре , даже когда я печатаю с клавиатуры .

Это поведение очень озадачивает.Может ли кто-нибудь помочь в этом?

Private LastPosition as Long  'declared in form module


Private sub t_LostFocus()     'to obtain last position in `TextBox`
    LastPosition = Me!t.SelStart
End Sub


Private Sub Insert()

Dim Text As String

   If LastPosition = 0 AND IsNull(Me!t.value) Then
      Me!t.Value = " " + Me.ActiveControl.Caption
      LastPosition = LastPosition + Len(Me.ActiveControl.Caption) + 1

   ElseIf LastPosition >=0 AND Not IsNull(Me!t.Value) Then
      Text = Me!t.Value
      Me!t.Value = Left(Text, LastPosition) & " " & Me.ActiveControl.Caption & Mid (Text, LastPosition + 1)
      LastPosition = LastPosition + Len(Me.ActiveControl.Caption)+1

   Else
      Me!t.Value = Me!t.Value + " " + Me.ActiveControl.Caption

   End If

End Sub

Private Sub button1_Click()
   Call Insert
End Sub

1 Ответ

1 голос
/ 12 апреля 2019

Сначала несколько фактов о вводе данных в форму доступа.Это необходимо понимать отдельно, чтобы правильно объяснить поведение, описанное в вопросе, и особенно, если кто-то пытается изменить поведение элемента управления по умолчанию.

  • TextBox.SelStart, SelLength и SelText доступны и действительны только тогда, когда элемент управления имеет фокус.Когда элемент управления TextBox снова получает фокус, по умолчанию выбирается весь текст, поэтому SelStart = 0 и SelLength = длина свойства Text.При использовании мыши и щелчке на TextBox в определенной позиции символа поведение по умолчанию игнорируется, и курсор помещается на курсор мыши, как и ожидалось.
  • Элементы управления TextBox имеют как свойство Text, так иValue собственность.Свойство Text представляет текстовую строку, отображаемую в элементе управления.Отображаемый текст может отличаться от базового значения, которое представляет элемент управления, особенно если Value является нетекстовым типом данных (например, целое число хранится как число, но представляется как отдельные текстовые цифры).Свойство Value возвращает вариант VBA, который сам содержит базовое значение определенного типа данных .
    • Для привязанного элемента управления (т. Е. Заполнено свойство ControlSource) тип данных Value будет таким же, как столбец связанного источника.
    • Для несвязанного элемента управления (т.е. ControlSource - пусто), тип данных Value определяется свойством TextBox.Format.Если Format пусто, то тип данных является текстовым и будет эффективно соответствовать свойству Text.
    • Text и Value не всегда синхронизируются, и это особенно верно, когда элемент управления имеет фокуси редактируется.Когда текст редактируется пользователем формы (т.е. не из кода), Value не обновляется до тех пор, пока элемент управления не потеряет фокус, или Shift + Enter не сохранит форму (кроме случаев, когда поведение клавиши Enter имеетбыли изменены).Большинство событий, которые обновят элемент управления, также включают щелчок или иное перемещение фокуса вне элемента управления , например сохранение записи, изменение фокуса на другой элемент управления и т. Д.
      • Когда элемент управления Valueобновляется, отображаемый текст - доступный через свойство Text - интерпретируется и / или преобразуется в соответствующий тип данных, который затем сохраняется в свойстве Value.(Иногда синхронизация продолжается, переформатируя «Значение» обратно в представление, указанное в свойстве Format. Например, если Format = Long Date, то: текст вводится как «4-12-19» -> обновленное значение: # 4/ 12/19 00: 00 # → обновленный текст: «Пятница, 12 апреля 2019 года».

Один важный последний факт, прежде чем я доберусь доточка:

  • Когда свойство TextBox.Value обновляется - даже если это также тип данных String - свойство Text также обновляется и положение курсора и выбор текста сбрасываются , так что весь текст выделяется. Другими словами, SelStart устанавливается на 0, а SelLength устанавливается на длину Text, так же, как поведение, наблюдаемое приTextBox вновь получает фокус (как упомянуто в первом пункте выше).

Наконец, суть всей этой детали :

  • Когдаклавиатура используется для изменения текста, это в конечном итоге вызовет обновление, но обычно не доКонтроль теряет фокус.Но когда происходит такое обновление, оно происходит за до события LostFocus и выбор текста сбрасывается, как описано выше, так что в обработчике LostFocus, SelStart == 0.
  • Theпроблема на самом деле не между клавиатурой и мышью, а между изменяемым или неизменяемым текстом элемента управления. Если в текстовом поле используются только клавиши со стрелками, то положение курсора и выбор текста сохраняются в событии LostFocus, поскольку элемент управленияобновление не произошло.Наоборот, если мышь используется для изменения текста (например, нажатие правой кнопкой мыши на Вставить), это также вызывает обновление, которое сбрасывает выделение.Фактически, если кто-либо изменяет текст каким-либо образом, а затем использует клавиши со стрелками или щелчки мыши, все равно будет происходить обновление и сбрасывается положение курсора и выбор текста.
    • Если фокус перемещается за пределы текстового поля, а затем снова с помощью мыши, возможно, произошло обновление, но мышь впоследствии установит позицию курсора.Я упоминаю об этом только для того, чтобы знать о случайных щелчках, которые могут не знать об обновлении и создавать иллюзию уникального поведения мыши.
  • Для ударов нажмите Shift+ Введите для принудительного обновления, но сохраните фокус на элементе управления и обратите внимание, что весь текст выбирается автоматически.

Стоит отследить код, поместив некоторые операторы «logging» вразличные события, так что вы можете наблюдать, когда они происходят и порядок.


Option Explicit
Option Compare Database

Dim LastSelStart As Integer
Dim LastSelLength As Integer
Dim UpdateSelStart As Integer
Dim UpdateSelLength As Integer

Private Sub button1_Click()
    Insert
End Sub

Private Sub button2_Click()
    Insert
End Sub

Private Sub Form_Load()
    LastSelStart = -1
    LastSelLength = 0
    ResetUpdateSelValues
End Sub

Private Sub ResetUpdateSelValues()
    UpdateSelStart = -1
    UpdateSelLength = 0
End Sub

Private Sub t_AfterUpdate()
    On Error Resume Next
    UpdateSelStart = Me.t.SelStart
    UpdateSelLength = Me.t.SelLength
    If Err.Number <> 0 Then
        UpdateSelStart = -1
    End If
End Sub

Private Sub t_GotFocus()
    On Error Resume Next
    If LastSelStart >= 0 Then
        Me.t.SelStart = LastSelStart
        Me.t.SelLength = LastSelLength
    End If
End Sub

Private Sub t_LostFocus()
    LastSelStart = Me.t.SelStart
    LastSelLength = Me.t.SelLength

    If LastSelStart = 0 And UpdateSelStart > 0 Then
        LastSelStart = UpdateSelStart
        LastSelLength = UpdateSelLength
    End If

    ResetUpdateSelValues
End Sub

Private Sub Insert()
    Dim caption As String
    caption = Me.ActiveControl.caption

    If IsNull(Me.t.Value) Then
        Me.t.Value = caption
        LastSelStart = Len(caption)
        LastSelLength = 0
    Else
        Dim Text As String
        Text = Me.t.Value

        If LastSelStart = 0 Then
            '* Don't add extra space at beginning
            Text = caption & Mid(Text, LastSelLength + 1)
            'Text = caption & Text
            LastSelStart = Len(caption)
            LastSelLength = 0
        ElseIf LastSelStart > 0 Then
            Text = Left(Text, LastSelStart) & " " & caption & Mid(Text, LastSelStart + LastSelLength + 1)
            'Text = Left(Text, LastSelStart) & " " & caption & Mid(Text, LastSelStart + 0 + 1)
            LastSelStart = LastSelStart + 1 + Len(caption)
            LastSelLength = 0
        Else
            'If last cursor position is invalid, append characters
            Text = Text & " " & caption
            LastSelStart = Len(Text)
            LastSelLength = 0
        End If

        t.Value = Text
    End If

    Me.t.SetFocus
End Sub
...