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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Автоматически выпадающий при наборе список, ищется модифицированный combobox 
:(
    Опции темы
AnTeml
Дата 23.5.2014, 05:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте.
Ищу компонент для реализации  выпадающего списка, как в поисковиках.


То есть, пользователь начинает вводить свою фамилию - и ему с сервера подставляется список, из которого он может выбрать свою или набирать дальше. Список будет уменьшаться.

примерно такой:
user posted image


Сам список формировать я хочу самостоятельно. Но всю отработку событий, фокусы ввода хотелось бы чтобы отрабатывал компонент.

В веб интерфейсах такое используется сплошь и рядом. Для делфей я нашёл только то, что кто-то ищет, а кто-то сам пишет, вроде этого:

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1387

ещё
http://delphikingdom.ru/asp/viewitem.asp?catalogid=1213

и ещё
http://www.codeproject.com/Articles/2224/A...-CCheckComboBox

Первый я даже попробовал (кстати с его странички и взят рисунок выше). Не без нареканий. Дорабатывать с ходу тяжко, нужно въезжать в код, а то в одном месте правишь - в другом вылазит.

Закралась мысль, быть может за последние годы что-нибудь поменялось, появились доработанные компоненты, а быть может даже в embarcadero их добавили?  Работаю в XE5.

Или посоветуйте какой-нибудь сторонний. Идеально было бы, чтобы можно было подставлять свой контрол для выбора, я бы вставил любимую VirtualTreeView
PM MAIL   Вверх
Poseidon
Дата 23.5.2014, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Такое можно сделать на базе стандартного ComboBox.


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Агрох
Дата 23.5.2014, 10:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 176
Регистрация: 6.4.2013
Где: Москва

Репутация: 3
Всего: 6



Или на связке TEdit + ListBox.

Добавлено через 11 минут и 5 секунд
Кидаешь на форму edit (Edit1) и прямо под ним, подогнав под размер, listbox (ListBox1) и ещё один, listbox (ListBox2) - невидимый. В ListBox2 загоняешь нефильтрованный список.

Код

Uses StrUtils;


Код

ListBox1.Style := lbOwnerDrawVariable;


Код

procedure TForm1.Edit1Change(Sender: TObject);
var
  i1: Integer;
begin
  for i1 := 0 to ListBox2.Items.Count - 1 do
  begin
    if (pos(AnsiUpperCase(Edit1.Text), AnsiUpperCase(ListBox2.Items[i1])) > 0) OR (Edit1.Text = '') then
    begin
      if ListBox1.Items.IndexOf(ListBox2.Items[i1]) = -1 then
        ListBox1.Items.Add(ListBox2.Items[i1]);
    end
    else
    begin
      if ListBox1.Items.IndexOf(ListBox2.Items[i1]) > -1 then
        ListBox1.Items.Delete(ListBox1.Items.IndexOf(ListBox2.Items[i1]));
    end;
  end;
  ListBox1.Visible := true;
  ListBox1.Repaint;
end;

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  Edit1Change(Edit1);
  ListBox1.Visible := true;
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  ListBox1.Visible := ListBox1.Focused;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  Edit1.Text := ListBox1.Items[ListBox1.ItemIndex];
  ListBox1.Visible := false;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  pos1: integer;
  s1, s2, s3: string;
  ListBox: TListBox;
begin
  ListBox := (Control AS TListBox);
  pos1 := pos(AnsiUpperCase(Edit1.Text), AnsiUpperCase(ListBox.Items[Index]));
  if pos1 > 0 then
  begin
    if pos1 > 1 then
    begin
      ListBox.Canvas.Font.Color := clBlack;
      s1 := Copy(ListBox.Items[Index], 1, pos1 - 1);
      ListBox.Canvas.TextOut(Rect.Left, Rect.Top, s1);
      ListBox.Canvas.Font.Color := clRed;
      s2 := Copy(ListBox.Items[Index], pos1, Length(Edit1.Text));
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1), Rect.Top, s2);
      ListBox.Canvas.Font.Color := clBlack;
      s3 := Copy(ListBox.Items[Index], pos1 + Length(Edit1.Text), Length(ListBox.Items[Index]) - (pos1 + Length(Edit1.Text)) + 1);
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1+s2), Rect.Top, s3);
    end
    else
    begin
      ListBox.Canvas.Font.Color := clRed;
      s1 := Copy(ListBox.Items[Index], 1, Length(Edit1.Text));
      ListBox.Canvas.TextOut(Rect.Left, Rect.Top, s1);
      ListBox.Canvas.Font.Color := clBlack;
      s2 := Copy(ListBox.Items[Index], Length(Edit1.Text) + 1, Length(ListBox.Items[Index]) - Length(Edit1.Text) + 1);
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1), Rect.Top, s2);
    end;
  end
  else
  begin
    ListBox.Canvas.Font.Color := clBlack;
    ListBox.Canvas.TextOut(Rect.Left, Rect.Top, ListBox.Items[Index]);
  end;
end;

--------------------
Putin here, Putin there, Putin almost everywhere!
PM MAIL   Вверх
Poseidon
Дата 23.5.2014, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Агрох, твой вариант не очень вяжется вот с этим:
Цитата(AnTeml @  23.5.2014,  05:04 Найти цитируемый пост)
Идеально было бы, чтобы можно было подставлять свой контрол для выбора, я бы вставил любимую VirtualTreeView 




--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Агрох
Дата 23.5.2014, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 176
Регистрация: 6.4.2013
Где: Москва

Репутация: 3
Всего: 6



Цитата(Poseidon @ 23.5.2014,  11:59)
Агрох, твой вариант не очень вяжется вот с этим:
Цитата(AnTeml @  23.5.2014,  05:04 Найти цитируемый пост)
Идеально было бы, чтобы можно было подставлять свой контрол для выбора, я бы вставил любимую VirtualTreeView 

Ну да, не учёл. Под дерево переписывать надо.
С VirtualTreeView не работал. У него с нодами работа так же организованна, как у обычного TreeView?
--------------------
Putin here, Putin there, Putin almost everywhere!
PM MAIL   Вверх
AnTeml
Дата 29.5.2014, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Poseidon @ 23.5.2014,  09:32)
Такое можно сделать на базе стандартного ComboBox.

без геморроя - никак!

включив AutoComplete с AutoDropDown при начале набора теряется фокус ввода в строке набора, т.е. больше одной буквы ничего не набрать

Добавлено через 5 минут и 58 секунд
Цитата(Агрох @ 23.5.2014,  10:40)
Или на связке TEdit + ListBox.

Добавлено @ 10:51
Кидаешь на форму edit (Edit1) и прямо под ним, подогнав под размер, listbox (ListBox1) и ещё один, listbox (ListBox2) - невидимый. В ListBox2 загоняешь нефильтрованный список.

Код

Uses StrUtils;


Код

ListBox1.Style := lbOwnerDrawVariable;


Код

procedure TForm1.Edit1Change(Sender: TObject);
var
  i1: Integer;
begin
  for i1 := 0 to ListBox2.Items.Count - 1 do
  begin
    if (pos(AnsiUpperCase(Edit1.Text), AnsiUpperCase(ListBox2.Items[i1])) > 0) OR (Edit1.Text = '') then
    begin
      if ListBox1.Items.IndexOf(ListBox2.Items[i1]) = -1 then
        ListBox1.Items.Add(ListBox2.Items[i1]);
    end
    else
    begin
      if ListBox1.Items.IndexOf(ListBox2.Items[i1]) > -1 then
        ListBox1.Items.Delete(ListBox1.Items.IndexOf(ListBox2.Items[i1]));
    end;
  end;
  ListBox1.Visible := true;
  ListBox1.Repaint;
end;

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  Edit1Change(Edit1);
  ListBox1.Visible := true;
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  ListBox1.Visible := ListBox1.Focused;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  Edit1.Text := ListBox1.Items[ListBox1.ItemIndex];
  ListBox1.Visible := false;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  pos1: integer;
  s1, s2, s3: string;
  ListBox: TListBox;
begin
  ListBox := (Control AS TListBox);
  pos1 := pos(AnsiUpperCase(Edit1.Text), AnsiUpperCase(ListBox.Items[Index]));
  if pos1 > 0 then
  begin
    if pos1 > 1 then
    begin
      ListBox.Canvas.Font.Color := clBlack;
      s1 := Copy(ListBox.Items[Index], 1, pos1 - 1);
      ListBox.Canvas.TextOut(Rect.Left, Rect.Top, s1);
      ListBox.Canvas.Font.Color := clRed;
      s2 := Copy(ListBox.Items[Index], pos1, Length(Edit1.Text));
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1), Rect.Top, s2);
      ListBox.Canvas.Font.Color := clBlack;
      s3 := Copy(ListBox.Items[Index], pos1 + Length(Edit1.Text), Length(ListBox.Items[Index]) - (pos1 + Length(Edit1.Text)) + 1);
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1+s2), Rect.Top, s3);
    end
    else
    begin
      ListBox.Canvas.Font.Color := clRed;
      s1 := Copy(ListBox.Items[Index], 1, Length(Edit1.Text));
      ListBox.Canvas.TextOut(Rect.Left, Rect.Top, s1);
      ListBox.Canvas.Font.Color := clBlack;
      s2 := Copy(ListBox.Items[Index], Length(Edit1.Text) + 1, Length(ListBox.Items[Index]) - Length(Edit1.Text) + 1);
      ListBox.Canvas.TextOut(Rect.Left + ListBox.Canvas.TextWidth(s1), Rect.Top, s2);
    end;
  end
  else
  begin
    ListBox.Canvas.Font.Color := clBlack;
    ListBox.Canvas.TextOut(Rect.Left, Rect.Top, ListBox.Items[Index]);
  end;
end;


Arpox, спасибо! Как временный вариант сойдёт. И свой компонент с таким же успехом можно подставить.

Пожалуй, единственный его минус  - то, что размеры компонента (в данном случае - листбокса) режутся размерами формы :(

то есть,если стандартный комбобокс разместить в самом низу формы, и нажать стрелочку вниз - оно прорисует его за пределы окна

Это сообщение отредактировал(а) AnTeml - 29.5.2014, 11:51
PM MAIL   Вверх
Akella
Дата 29.5.2014, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



Цитата(AnTeml @  29.5.2014,  11:49 Найти цитируемый пост)
включив AutoComplete с AutoDropDown при начале набора теряется фокус ввода в строке набора, т.е. больше одной буквы ничего не набрать

набрать, если набирать с нормальной скоростью
но проблема в том, что работает только с началом строки
PM MAIL   Вверх
AnTeml
Дата 30.5.2014, 04:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нет, выкидывает сразу. Ни с какой скоростью не набрать, разве что набрать в другом месте и скопировать....

Но дело в другом - мне вообще не нужна автоподстановка, список, в зависимости от набранного, формируется на сервере (!!!)

я просто безмерно удивлён тем фактом, что нет готового компонента

в веб интерфейсах на различных сайтах это работает и используется сплошь и рядом!!

а тут надо какие-то костыли забивать
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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