Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Забывает ListIndex хоть убей... Почему? Добавлено: 14.08.05 14:08  

Автор вопроса:  П.С. | Web-сайт: psbatishev.narod.ru | ICQ: 225019134 
Имеется код (приведен ниже), который позволяет быстро выбирать в поле со списком (cm) строку путем набора первых символов. И все бы хорошо, но после установки ListIndex в нужное значение тут же его забывает. Например, если после набора нескольких букв нажать на кнопку Command1, то выдает -1. Почему? Тестировал до умопомрачения, но не нашел. Конечно, если нажать еще и стрелку вниз, то все нормально, но весь смысл в том, чтобы этого не делать.

PS:Комбо должено быть предварительно заполнено строками.
PS:Буду признателен, если кто-нибудь прольет свет. Спасибо.

Private Sub Command1_Click()
    MsgBox Cm.ListIndex
End Sub

Private Sub cm_Change()
'Добавление символов, уменьшение выделения
    On Error Resume Next
    Dim Sod As String, Kol, i As Integer
    Sod = Cm.Text
    If Sod <> "" Then
        Kol = Len(Sod)
        For i = 0 To Cm.ListCount - 1
            If UCase(Sod) = UCase(Left(Cm.List(i), Kol)) Then
                Cm.ListIndex = i
                Cm.Text = Cm.List(i)
                Cm.SelStart = Kol
                Cm.SelLength = Len(Mid(Cm.List(i), Kol + 1))
                Exit For
            End If
        Next i
    End If
End Sub

Private Sub Cm_KeyDown(KeyCode As Integer, Shift As Integer)
'Увеличение выделения при нажатии BS
    If KeyCode = vbKeyBack Then
        Dim i As Integer
        i = Len(Cm.SelText)
        If Cm.Text <> Cm.SelText Then
            Cm.SelStart = Cm.SelStart - 1
            Cm.SelLength = i + 1
        End If
    End If
End Sub

Ответить

  Ответы Всего ответов: 12  

Номер ответа: 1
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #1 Добавлено: 14.08.05 14:21
Лично я автозаполнение делаю так.

Private Sub cmbStreet_Change()
  If Len(cmbStreet.Tag) = 0 Then DoAutoCompleteCombo cmbStreet
End Sub

Private Sub cmbStreet_KeyDown(KeyCode As Integer, Shift As Integer)
  Select Case KeyCode
  Case vbKeyDelete, vbKeyBack
    cmbStreet.Tag = "0"
  Case Else
    cmbStreet.Tag = vbNullString
  End Select
End Sub

Public Sub DoAutoCompleteCombo(ByVal c As ComboBox)
  Dim p As Long, t As Long
  
  If c.Style <> vbComboDropdownList Then
    p = SendMessage(c.hWnd, CB_FINDSTRING, -1&, ByVal c.Text)
    If p <> CB_ERR Then
      t = c.SelStart
      c.ListIndex = p
      c.SelStart = t
      c.SelLength = Len(c.Text) - t
    End If
  End If
End Sub

Ответить

Номер ответа: 2
Автор ответа:
 П.С.



ICQ: 225019134 

Вопросов: 36
Ответов: 41
 Web-сайт: psbatishev.narod.ru
 Профиль | | #2
Добавлено: 14.08.05 16:23
Испробовал твой код (правда без функции SendMessage, предполагаю, что в ней должно быть). Итог: то же самое. Если добавить кнопочку, щелкнуть да по ней, и ввыведено будет -1, т.е. ListIndex никак не держится, хотя этому свойству значение было присвоено (в обоих вариантах кодов), и оно верно в пределах события Click, например...

Может есть какой секрет?

Ответить

Номер ответа: 3
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #3 Добавлено: 14.08.05 16:57
Function GetComboValidIndex(ByVal c As ComboBox) As Long
  If c.Style = vbComboDropdownList Then
    GetComboValidIndex = c.ListIndex
  Else
    GetComboValidIndex = SendMessage(c.hWnd, CB_FINDSTRINGEXACT, -1&, ByVal c.Text)
  End If
End Function

Ответить

Номер ответа: 4
Автор ответа:
 П.С.



ICQ: 225019134 

Вопросов: 36
Ответов: 41
 Web-сайт: psbatishev.narod.ru
 Профиль | | #4
Добавлено: 14.08.05 17:00
Уточни, пожалуйста, что это за функция SendMessage? Какой код она содержит?

Ответить

Номер ответа: 5
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #5 Добавлено: 14.08.05 17:05
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long

Ответить

Номер ответа: 6
Автор ответа:
 Black Dragon



ICQ: 321186096 

Вопросов: 30
Ответов: 347
 Web-сайт: в разработке
 Профиль | | #6
Добавлено: 14.08.05 18:12
2 П.С. это API

Ответить

Номер ответа: 7
Автор ответа:
 П.С.



ICQ: 225019134 

Вопросов: 36
Ответов: 41
 Web-сайт: psbatishev.narod.ru
 Профиль | | #7
Добавлено: 14.08.05 18:50
Спасибо за разъяснения и участие! Все у меня заработало и в твоем варианте, но проблема осталась та же. Если сделать на форме кнопку и например такой код события кнопки:

MsgBox cmbStreet.ListIndex

то выдает -1 ....
Почему?

Ответить

Номер ответа: 8
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #8 Добавлено: 15.08.05 00:08
Почему, почему...
Потому, что комбобокс состоит из двух частей - едита и падающего списка. Оттого, что ты в едите отобразил строку, состояние списка не меняется. Как было -1 (ничего не выбрано) так и осталось.
А чтобы в списке тоже произошли изменения (изменился индекс) надо ткнуть его носом в этот индекс:

Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
                                        ByVal hwnd As Long, _
                                        ByVal wMsg As Long, _
                                        ByVal wParam As Long, _
                                        ByRef lParam As Any) As Long
                                        
Private Const CB_SELECTSTRING As Long = &H14D

Private Sub Cm_Change()
    On Error Resume Next
    Dim Sod As String, Kol, i As Integer
    Sod = Cm.Text
    If Sod <> "" Then
        Kol = Len(Sod)
        For i = 0 To Cm.ListCount - 1
            If UCase(Sod) = UCase(Left(Cm.List(i), Kol)) Then
                Cm.ListIndex = i
                Cm.Text = Cm.List(i)
                Cm.SelStart = Kol
                Cm.SelLength = Len(Mid(Cm.List(i), Kol + 1))
                Exit For
            End If
        Next i
    End If
End Sub

Private Sub Cm_Keydown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyBack Then
        Dim i As Integer
        i = Len(Cm.SelText)
        If Cm.Text <> Cm.SelText Then
            Cm.SelStart = Cm.SelStart - 1
            Cm.SelLength = i + 1
        End If
    End If
End Sub

Private Sub Cm_KeyUp(KeyCode As Integer, Shift As Integer)
    Dim ret As Long
    If (Len(Cm.Text) <> 0) Then
        ret = SendMessage(Cm.hwnd, CB_SELECTSTRING, -1, ByVal Cm.Text)
        If ret <> -1 Then Cm.ListIndex = ret
    End If
End Sub

Private Sub Command1_Click()
    MsgBox Cm.ListIndex
End Sub

Ответить

Номер ответа: 9
Автор ответа:
 Sur



ICQ: 1249088 

Вопросов: 10
Ответов: 304
 Web-сайт: sur.hotbox.ru/
 Профиль | | #9
Добавлено: 15.08.05 15:00
Если Cm.ListIndex есть и верно в событии cm_Change(), то не проще ли его там глобально запомнить
CmListIndex = Cm.ListIndex и вызывать CmListIndex уже в других процедурах.

PS. Как вы боретесь с тем, что другие значения (кроме тех, что в списке) уже фиг введешь?

Ответить

Номер ответа: 10
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #10 Добавлено: 15.08.05 15:10
Если Cm.ListIndex есть и верно в событии cm_Change(), то не проще ли его там глобально запомнить

В том и дело, что его нет. Ничего не выбрано, индекс = -1. А "событие" не происходит при наборе текста в едите. Поэтому эта затея бесперспективна, т.к. нужно чтобы при наборе текста менялся индекс

Ответить

Номер ответа: 11
Автор ответа:
 Sur



ICQ: 1249088 

Вопросов: 10
Ответов: 304
 Web-сайт: sur.hotbox.ru/
 Профиль | | #11
Добавлено: 15.08.05 15:26
Что, тлько у меня есть? Проверял?

Ответить

Номер ответа: 12
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #12 Добавлено: 15.08.05 15:44
Почитай ещё раз всю тему: автор в каждом посте жалуется, что у него ListIndex = -1.
А у тебя видимо волшебный комбобокс, который при наборе текста вызывает событие Change()

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам