cmbComboBox.SelectionStart始终返回零,而与光标位置无关

时间:2018-08-19 05:31:12

标签: vb.net combobox

由于某些原因,从文本框到组合框,“ SelectionStart”属性的行为有所不同。

创建一个TextBox和一个ComboBox。确保DropDownStyle = DropDown(不是DropDownList!)

添加以下请假事件(如果使用LostFocus事件,则结果相同):

Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave
    Debug.Print("Textbox:  " & TextBox1.SelectionStart)
End Sub

Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
    Debug.Print("ComboBox: " & ComboBox1.SelectionStart)
End Sub

现在在每个控件中键入文本,并在控件之间更改焦点,选择光标位于字符串的不同位置。

我明白了:

Textbox:  6
ComboBox: 0
Textbox:  8
ComboBox: 0
Textbox:  5
ComboBox: 0
Textbox:  4
ComboBox: 0
... and so on

当文本框失去焦点时,它将返回正确的SelectionStart。 当组合框失去焦点时,它始终返回零。

是否有原因,解决方案或合理的解决方法?我似乎无法在没有为每个组合控件创建新变量并在每次单击和按键事件上存储SelectionStart的情况下进行拦截(假设用户可能单击鼠标,使用箭头键或键入字符)。

3 个答案:

答案 0 :(得分:0)

我刚刚进行了一些测试,似乎在LeaveLostFocus事件之间以及在EnterGotFocus事件之间重置了选择。我试过记住每对中第一个的值,然后在第二对中恢复它,然后按需要工作:

Private comboBox1SelectionStart As Integer
Private comboBox1SelectionLength As Integer

Private Sub ComboBox1_Enter(sender As Object, e As EventArgs) Handles ComboBox1.Enter
    comboBox1SelectionStart = ComboBox1.SelectionStart
    comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub

Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
    comboBox1SelectionStart = ComboBox1.SelectionStart
    comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub

Private Sub ComboBox1_GotFocus(sender As Object, e As EventArgs) Handles ComboBox1.GotFocus
    ComboBox1.SelectionStart = comboBox1SelectionStart
    ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub

Private Sub ComboBox1_LostFocus(sender As Object, e As EventArgs) Handles ComboBox1.LostFocus
    ComboBox1.SelectionStart = comboBox1SelectionStart
    ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub

您不想每次都CokmboBox都这样做,因此可以将其构建到自定义控件中,然后使用它代替标准控件:

Public Class ComboBoxEx
    Inherits ComboBox

    Private selectionStartTemp As Integer
    Private selectionLengthTemp As Integer

    Protected Overrides Sub OnEnter(e As EventArgs)
        MyBase.OnEnter(e)

        'Remember the current selection.
        selectionStartTemp = SelectionStart
        selectionLengthTemp = SelectionLength
    End Sub

    Protected Overrides Sub OnGotFocus(e As EventArgs)
        'Restore the selection.
        SelectionStart = selectionStartTemp
        SelectionLength = selectionLengthTemp

        MyBase.OnGotFocus(e)
    End Sub

    Protected Overrides Sub OnLeave(e As EventArgs)
        MyBase.OnLeave(e)

        'Remember the current selection.
        selectionStartTemp = SelectionStart
        selectionLengthTemp = SelectionLength
    End Sub

    Protected Overrides Sub OnLostFocus(e As EventArgs)
        'Restore the selection.
        SelectionStart = selectionStartTemp
        SelectionLength = selectionLengthTemp

        MyBase.OnLostFocus(e)
    End Sub

End Class

此操作的一个副作用是,即使控件没有焦点,您也会看到所选的文本。 ComboBox没有HideSelection那样的TextBox属性。如果您不喜欢这样,那么我会想像您可以找到一种使它像TextBox那样运行的方法,但这是一个不同的问题,因此在这里我不再赘述。

答案 1 :(得分:0)

我想我已经理解了,使用您的想法,只是将值设置在其他位置。

Dim ComboSelectionStart As Integer

Private Sub cmbComboBox_KeyUp(sender As Object, e As KeyEventArgs) Handles cmbComboBox.KeyUp
    'Store selection on any key press
    ComboSelectionStart = cmbComboBox.SelectionStart
End Sub

Private Sub cmbComboBox_MouseClick(sender As Object, e As MouseEventArgs) Handles cmbComboBox.MouseClick
    'Store selection on any mouse click
    ComboSelectionStart = cmbComboBox.SelectionStart
End Sub

Private Sub cmbComboBox_Leave(sender As Object, e As EventArgs) Handles cmbComboBox.Leave
    'Returns correct value here because it was not altered by LostFocus event
    Debug.Print(ComboSelectionStart .ToString)
End Sub

答案 2 :(得分:0)

在@jmcilhinney提供的类中修改OnLeave()子元素时,它实际上可以很好地工作。

{{1}}