Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выпадающий список в ComboBox 
:(
    Опции темы
Albinos_x
Дата 23.4.2005, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Тут возник у меня вопрос:
Как сделать фильтрацию в выпадающем списке в ComboBox, в зависимости от набраемой строки.
Т.е. сделать приблизительно то же, что и в Делфи по нажатью "Ctrl+Space" только в ComboBox-е



--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Garmahis
Дата 23.4.2005, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 23.12.2004

Репутация: нет
Всего: 4



Пример помойму из DRKB

Код

var 
  LastKey: Word; 

procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word; 
  Shift: TShiftState); 
begin 
  LastKey := Key; 
end; 

procedure TForm1.ComboBox1Change(Sender: TObject); 
var 
  Srch: string; 
  ix: Integer; 
begin 
  Srch := combobox1.Text; 
  if LastKey = $08 then 
  begin 
    LastKey := 0; 
    Exit; 
  end; 
  LastKey := 0; 
  ix := combobox1.Perform(CB_FINDSTRING, - 1, Longint(PChar(Srch))); 
  if ix > CB_ERR then 
  begin 
    combobox1.ItemIndex := ix; 
    combobox1.SelStart  := Length(Srch); 
    combobox1.SelLength := (Length(combobox1.Text) - Length(Srch)); 
  end; 
end;




Это сообщение отредактировал(а) Garmahis - 23.4.2005, 11:38
PM   Вверх
Albinos_x
Дата 23.4.2005, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Не... этот код не делает фильтрацию... Он просто выбирает по набронному из списка
тоже самое можно сделать
Код

combobox1.AutoComplete:=true;





--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 23.4.2005, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Код

var
 i:integer;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ComboBox1.Items.Clear;
 for i:=0 to ListBox1.Items.Count-1 do
  begin
   if Copy(ListBox1.Items[i], 1, Length(ComboBox1.Text)) = ComboBox1.Text
    then
     ComboBox1.Items.Add(ListBox1.Items[i]);
   Application.ProcessMessages
  end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 for i:=0 to ListBox1.Items.Count-1 do
  begin
   ComboBox1.Items.Add(ListBox1.Items[i]);
   Application.ProcessMessages
  end
end;

Где в спрятанном ListBox'е хранится полный список...
Добавлено @ 12:46
Вот только большой список не очень красиво работать будет... smile
Добавлено @ 12:47
С тысячей быстро справляется...
PM   Вверх
Albinos_x
Дата 23.4.2005, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



У меня был подобный вариант, но в нем как и в этом возникает проблема: курсор при каждом выполнении процедуры перемещяется в начало текста, что приводит к тому что текст набирается в обратном порядке


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 23.4.2005, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Код

 ComboBox1.Items.Clear;
 for i:=0 to ListBox1.Items.Count-1 do
  begin
   if Copy(ListBox1.Items[i], 1, Length(ComboBox1.Text)) = ComboBox1.Text
    then
     ComboBox1.Items.Add(ListBox1.Items[i]);
   Application.ProcessMessages
  end;
 ComboBox1.SelStart:=Length(ComboBox1.Text); // Вот это возращает курсор в конец текста

PM   Вверх
Albinos_x
Дата 23.4.2005, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Большое спасибо!

А есть возможность считывать положение курсора и его устанавливать в назначенную позицию?
// допустим пользователь совершил опечатку. Он нажмет Del или BackSpase курсор переместится в конец - это не есть хорошо...


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 23.4.2005, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Код

var
 s:string;
 j:integer;
begin
 s:=ComboBox1.Text;
 ComboBox1.Items.Clear;
 j:=0;
 for i:=0 to ListBox1.Items.Count-1 do
  begin
   if Copy(ListBox1.Items[i], 1, Length(s)) = s
    then
     begin
      ComboBox1.Items.Add(ListBox1.Items[i]);
      if ListBox1.Items[i] = s
       then
        j:=ComboBox1.Items.Count-1;
     end;
   Application.ProcessMessages
  end;
 ComboBox1.ItemIndex:=j;
 ComboBox1.SelStart:=Length(s);

Теперь еще можно и выбирать из списка элемент... и не бояться за ItemIndex...
Добавлено @ 13:49
Код

 ComboBox1.SelStart:=length(s)-1;

На предпоследнюю позицию...

P. S.
Пояcни конкретнее задачу про DEL... ^)
PM   Вверх
Albinos_x
Дата 23.4.2005, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Цитата
P. S.
Пояcни конкретнее задачу про DEL...


допустим пользователь набрал вместо Albinos_x -> Alninos_x, ему надо пеменять букву 'n' на букву 'b'. Он устанавливает курсор перед буквой 'n' и нажимает Del, курсор перемещяется в конец текста. Он по невнимательности нажимает 'b' и получает Alinos_xb. Даже если он будет внимательным, то каждый раз перемещять курсор не очень удобно...

Цитата
...Теперь еще можно и выбирать из списка элемент... и не бояться за ItemIndex...


Этот вариант не покатит

Это сообщение отредактировал(а) Albinos_x - 23.4.2005, 14:06


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 23.4.2005, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Ok... щас доработаю исключения на данные клавиши... smile
PM   Вверх
Pakshin A. S.
Дата 23.4.2005, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Идея такова:
1) Добавляем новую глобальную переменную
Код

flag: boolean;

2) Делаем еще один обработчик
Код

procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
 flag:=key <> #8
end;

3) Изменяем процедуру:
Код

procedure TForm1.ComboBox1Change(Sender: TObject);
var
 s:string;
 j:integer;
begin
 if flag
  then
   begin
    s:=ComboBox1.Text;
    ComboBox1.Items.Clear;
    j:=-1;
    for i:=0 to ListBox1.Items.Count-1 do
     begin
      if Copy(ListBox1.Items[i], 1, Length(s)) = s
       then
        begin
         ComboBox1.Items.Add(ListBox1.Items[i]);
         if ListBox1.Items[i] = s
          then
           j:=ComboBox1.Items.Count-1;
        end;
      Application.ProcessMessages
     end;
    ComboBox1.ItemIndex:=j;
    ComboBox1.SelStart:=Length(s)
   end
 else
  flag:=true
end;


А вот по поводу кнопочки Del... пока не получается...

P. S.
То, что надо реализовал? Или надо что-то иное?
PM   Вверх
Albinos_x
Дата 23.4.2005, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



к сожалению, нет...
почти что как надо работает первый предложенный тобой вавриант...

второй делает выборку по первому символу, а третий - последний - при удалении символов не возвращяет ранее отфильтрованное...Знаю в чём проблема, но не заню как решить.

Решение было бы проще если можно было считывать и также устанавливать позицию курсора...
Добавлено @ 20:17
Цитата
А вот по поводу кнопочки Del... пока не получается...


с этим не получается потому, что Key почему-то не возвращяет значение нажатие этой кнопки.. я пробовал делать #46 {VK_DELETE}, но не помогает


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 23.4.2005, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



М-дя... Так... Скажи четко, что тебе нужно и я попробую все это реальзовать... Опиши различные ситуации и выборки...
PM   Вверх
Albinos_x
Дата 24.4.2005, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Нужна фильтрация, чтобы в списке отображалось только то, что совпадает по маске с набранным(имеющимся) в комбобоксе. И чтобы с этим было удобно работать (имею ввиду что поведение курсора не должно отличатся от стандартного поверения)


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 24.4.2005, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Ну первое, думаю уже реализовано... причем работает нормально...

Теперь второе... что подразумевается под "поведение курсора не должно отличатся от стандартного поверения"... Идеально - приведи пример типа такого:
1) Вводим ыва
2) Переходим в позицию и нажимаем что-то
3) У нас должно получиться то-то...
4) и т. д. и т. п.

smile
PM   Вверх
Albinos_x
Дата 24.4.2005, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Пример:

1. введено 'Alninos_x|'
2. переходим в позицию 'Al|ninos_x' или 'Aln|inos_x'
3. нажимием #Del или #BackSpace cooтветственно
4. получаем 'Al|inos_x'
5. нажимаем 'b'
6. получаем ' Alb|inos_x'

где | - позиция курсора

PS: в принципе, выше есть пример.
Просто, в проге хочу учесть все возможные действия пользователя и совместить с удобством работы в ней


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 24.4.2005, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Делаем упомянутый выше обработчик на нажатие клавиши...
и изменяем процедуру:
Код

procedure TForm1.ComboBox1Change(Sender: TObject);
var
 s:string;
 j:integer;
begin
    s:=ComboBox1.Text;
    ComboBox1.Items.Clear;
    j:=-1;
    for i:=0 to ListBox1.Items.Count-1 do
     begin
      if Copy(ListBox1.Items[i], 1, Length(s)) = s
       then
        begin
         ComboBox1.Items.Add(ListBox1.Items[i]);
         if ListBox1.Items[i] = s
          then
           j:=ComboBox1.Items.Count-1;
        end;
      Application.ProcessMessages
     end;
    ComboBox1.ItemIndex:=j;
    if flag
     then
      ComboBox1.SelStart:=Length(s)
     else
      flag:=true;
   end
end;

PM   Вверх
Albinos_x
Дата 24.4.2005, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



В этом случае курсор перемещяется в начало текста... что в принципе не отличается от других вариантов...

Ладно сделаю пока так как есть...
Вот что получилось:


Код
...
var
  List : TStringList;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
...
List:=TStringList.Create;
ComboBox1.Tag:=1:
...
end;

....

procedure TForm1.ComboBox1Enter(Sender: TObject);
begin
IniFilter(Table1,inttostr(ComboBox1.Tag));
IniList(Table1, List);
ComboBox1.Items:=List;
end;

procedure FilterComboList(Combo: TComboBox; L:TStringList);
var i, k:word;
begin
k:=L.Count;
if k<>0 then
   begin
   Combo.Items.Clear;
   for i:=0 to (k-1) do
      begin
      if AnsiLowerCase(Copy(L.Strings[i], 1, Length(Combo.Text))) = AnsiLowerCase(Combo.Text) then
         Combo.Items.Add(L.Strings[i]);
      Application.ProcessMessages;
      end;
   Combo.SelStart:=Length(Combo.Text);
   end;
end;
...
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
FilterComboList(ComboBox1, List);
end;
...



--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 24.4.2005, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



О! Вспомнил.... Вроде так получится

Код

procedure TForm1.ComboBox1Change(Sender: TObject);
var
 s:string;
 j,k:integer;
begin
    s:=ComboBox1.Text;
    k:=ComboBox1.SelStart;
    ComboBox1.Items.Clear;
    j:=-1;
    for i:=0 to ListBox1.Items.Count-1 do
     begin
      if Copy(ListBox1.Items[i], 1, Length(s)) = s
       then
        begin
         ComboBox1.Items.Add(ListBox1.Items[i]);
         if ListBox1.Items[i] = s
          then
           j:=ComboBox1.Items.Count-1;
        end;
      Application.ProcessMessages
     end;
    ComboBox1.ItemIndex:=j;
    if flag
     then
      ComboBox1.SelStart:=Length(s)
     else
      ComboBox1.SelStart:=k;
      flag:=true;
   end
end;


Да, так работает... курсор сохраняет позицию...
Добавлено @ 13:20
Кстати, а почему ты не изменяешь ItemIndex? У меня без него нельзя было выбрать корректно элемент из списка... smile
PM   Вверх
Albinos_x
Дата 24.4.2005, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



Ок!!! Всё работает!!!

Внес изменения в
Код

procedure FilterComboList(Combo: TComboBox; L:TStringList);
var i, k:word;
    pos:word;
    j: integer;
begin
pos:=Combo.SelStart;
k:=L.Count;
j:=-1;
if k<>0 then
   begin
   Combo.Items.Clear;
   for i:=0 to (k-1) do
      begin
      if AnsiLowerCase(Copy(L.Strings[i], 1, Length(Combo.Text))) = AnsiLowerCase(Combo.Text) then
         begin
         Combo.Items.Add(L.Strings[i]);
         if L.Strings[i] = Combo.Text then
            j:=Combo.Items.Count-1;
         end;
      Application.ProcessMessages;
      end;
   Combo.ItemIndex:=j;
   Combo.SelStart:=pos;
   end;
end;


Цитата
Кстати, а почему ты не изменяешь ItemIndex? У меня без него нельзя было выбрать корректно элемент из списка...


Не заметил косяк, увлёкся фильтрацией и курсором... Спасибо за замечание!... smile

Спавибо за оказанную помощь!!! smile
Добавлено @ 14:32
Pakshin A. S.
+1


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 24.4.2005, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Не за что... рад немного подсобить... обращайся, если что не так пойдет... smile
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0975 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.