• 0
VirusZ2D

Сортировка TListBoxItem по алфавиту

Вопросы

Доброго времени суток

 

как отсортировать по алфавиту  Listbox1.sorted := true;

если так то он сортирует начиная с цифр а хотелось бы чтоб он начинал  с букв можно ли научить listbox этому ? спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 ответа на этот вопрос

  • 0

Незнаю, можно ли напрямую сортировку делать - но можно воспользоваться кастомной сортировкой массива. Возможно у меня не совсем правильно - но вот работающий пример:

 TArray.Sort<String>(YouArrayName, TDelegatedComparer<String>.Construct(
    function(const Left, Right: String): Integer
    var
      Custom: TCustomerComparer;
    begin
      Custom := TCustomerComparer.Create;
      try
        Result := Custom.Compare(Left, Right);
      finally
        Custom.Free;
      end;
    end));

TCustomerComparer.Compare(Left, Right); - ваш вариант сортировки. Я брал реализацию Александра (Rouse_) Багеля. Выглядит она так:

{ TCustomerComparer }

function TCustomerComparer.Compare(const Left, Right: String): Integer;
var
  S1IsInt, S2IsInt: Boolean;
  S1Cursor, S2Cursor: PChar;
  S1Int, S2Int, Counter, S1IntCount, S2IntCount: Integer;
  SingleByte: Byte;
begin
  // Проверка на пустые строки
  if Left = '' then
    if Right = '' then
    begin
      Result := 0;
      Exit;
    end
    else
    begin
      Result := -1;
      Exit;
    end;
  if Right = '' then
  begin
    Result := 1;
    Exit;
  end;

  S1Cursor := @AnsiLowerCase(Left)[1];
  S2Cursor := @AnsiLowerCase(Right)[1];

  while True do
  begin
    // проверка на конец первой строки
    if S1Cursor^ = #0 then
      if S2Cursor^ = #0 then
      begin
        Result := 0;
        Exit;
      end
      else
      begin
        Result := -1;
        Exit;
      end;

    // проверка на конец второй строки
    if S2Cursor^ = #0 then
    begin
      Result := 1;
      Exit;
    end;

    // проверка на начало числа в обоих строках
    S1IsInt := CharInSet(S1Cursor^, ['0' .. '9']);
    S2IsInt := CharInSet(S2Cursor^, ['0' .. '9']);
    if S1IsInt and not S2IsInt then
    begin
      Result := -1;
      Exit;
    end;
    if not S1IsInt and S2IsInt then
    begin
      Result := 1;
      Exit;
    end;

    // посимвольное сравнение
    if not(S1IsInt and S2IsInt) then
    begin
      if S1Cursor^ = S2Cursor^ then
      begin
        Inc(S1Cursor);
        Inc(S2Cursor);
        Continue;
      end;
      if S1Cursor^ < S2Cursor^ then
      begin
        Result := -1;
        Exit;
      end
      else
      begin
        Result := 1;
        Exit;
      end;
    end;

    // вытаскиваем числа из обоих строк и сравниваем
    S1Int := 0;
    Counter := 1;
    S1IntCount := 0;
    repeat
      Inc(S1IntCount);
      SingleByte := Byte(S1Cursor^) - Byte('0');
      S1Int := S1Int * Counter + SingleByte;
      Inc(S1Cursor);
      Counter := 10;
    until not CharInSet(S1Cursor^, ['0' .. '9']);

    S2Int := 0;
    Counter := 1;
    S2IntCount := 0;
    repeat
      SingleByte := Byte(S2Cursor^) - Byte('0');
      Inc(S2IntCount);
      S2Int := S2Int * Counter + SingleByte;
      Inc(S2Cursor);
      Counter := 10;
    until not CharInSet(S2Cursor^, ['0' .. '9']);

    if S1Int = S2Int then
    begin
      if S1Int = 0 then
      begin
        if S1IntCount < S2IntCount then
        begin
          Result := -1;
          Exit;
        end;
        if S1IntCount > S2IntCount then
        begin
          Result := 1;
          Exit;
        end;
      end;
      Continue;
    end;
    if S1Int < S2Int then
    begin
      Result := -1;
      Exit;
    end
    else
    begin
      Result := 1;
      Exit;
    end;
  end;
end;

Загрузка в ЛистБокс:

ListBox11.Items.AddStrings(YouArrayName);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

что ж так сложно то O_O

выделить из строки подстроку - на 100 строк процедура?

 

а еще как обычно замечу, что данные нужно хранить в модели данных а не на экране

тогда доступ к ним гораздо проще

и сортировка тоже

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

что ж так сложно то O_O

выделить из строки подстроку - на 100 строк процедура?

 

а еще как обычно замечу, что данные нужно хранить в модели данных а не на экране

тогда доступ к ним гораздо проще

и сортировка тоже

действительно спасибо засыпал уже не подумал )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От Леонид Кудацкий
      Процедура  Process заполняет Listbox:
      procedure TForm1.Process;
      Const
         N=100;
      var
        I,Index:Integer;
        Item:TListBoxItem;
      begin
      for I := 1 to N do
          begin
          Item:=TListBoxItem.Create(ListBox1);
          Item.Text:=IntToStr(I);
          ListBox1.AddObject(Item);
          end;
      ListBox1.ScrollToItem(Item);
      end;
      Нужно, чтобы после заполнения Listbox скролировал в конец.
      Если процедура запускается нажатием кнопки, то всё нормально.
      А если из события формы FormCreate, то Listbox заполняется,
      а скролирование не происходит.
      Где тут собака порылась ?
    • От Sergiy_83
      Всем привет.
      Иногда, особенно когда есть прокрутка списка можно случайно выделить несколько элементов ListBox-а. Ощущение, что чем больше загрузка приложения, тем чаще проявляет себя эта проблема. Бывает редко но жутко раздражает. Работоспособность программы не нарушается.
      Что делать? Может "костыли" какие возможно придумать? 
      Android.
    • От YurMak
      Здравствуйте, уважаемые!
      Пробую писать некое подобие файлового менеджера.
      Для вывода папок и файлов использую  ListBox .
      Так вот: при обработке события ListBoxItemClick (нажатие  на строку) происходит переход по пути, казанному с этой строке, содержимое этой папки отображается, но строки в ней не нажимаютмя, не реагируют на событие нажатия.
      Если проще - строки на первой станице ListBox реагируют на нажатие, а на второй - нет.
      Что я делаю не так?
      {Клик по Item'у, вперёд} procedure TForm1.FoldersListBoxItemClick(const Sender: TCustomListBox; const Item: TListBoxItem); var ExtFile: string; begin // Сохраняем выбранный путь CurrentPath := CurrentPath+Item.ItemData.Text; //Текущая директория if Item.TagString = 'folder' then //Проверяем, если это папка begin if TDirectory.Exists(CurrentPath) then //Проверяем, если папка существует begin Label1.Text:= 'Нажата строка № '+ inttostr(Item.Index); //Контроль!!! FillFolderListBox(CurrentPath, True); //Процедура заполнения ListBox`а папками и файлами end else if Item.TagString = 'file' then //Иначе - файл begin Label1.Text:='Отправляем файл "'+Item.ItemData.Text+'" на плеер'; //Готовим на исподнение end; end; end; Вот этот код срабатывает один (первый) раз.
       
      Прошу помощи, советов, вариантов.
    • От Sashar333
      Здравствуйте!
      Есть ListBox1, на нем разное кол-во tlistboxitem'ов, на каждом tlistboxitem'е есть один tgridpanellayout состоящий из четырех колонок и одной строчи, в каждой колонке
      по одному trectangle, в каждом trectangle по одному ttext с именами по очереди типа 'w'+IntToStr(Item.index), 'l'+IntToStr(Item.index), 'k'+IntToStr(Item.index)
      такие имена для Ttext требуются для дальнейшей обработки и распознования, в каждом Ttext надпись, на примере "-","2","2","Х" :

      при нажатии на текст "Х" удаляется tlistboxitem c помощью listbox1.Items.Delete(indexclick)
      Проблема следующая, при создании нового итема пишет дубликат имени Ttext, я так понял что итем удалился а то что на нем -нет
      как можно быстро удалить и итем и то что на нем находилось? Пример создания итема:
      procedure addrazmer(zap:typezap); var item:tlistboxitem; pg:tgridpanellayout; t1,t2,t3,t4:ttext; al:talignlayout; r1,r2,r3,r4:trectangle; i:integer; begin form1.listbox1.BeginUpdate; while Form1.listbox1.Count<>1 do Form1.listbox1.Items.Delete(0); for i := 0 to length(zap.razmer)-1 do begin item:=tlistboxitem.Create(form1.listbox1); item.Height:=30; pg:=tgridpanellayout.Create(item); pg.RowCollection[1].Value:=0; pg.ColumnCollection.Add;pg.ColumnCollection[2].Value:=50; pg.ColumnCollection.Add;pg.ColumnCollection[3].Value:=10; pg.Parent:=item; pg.Align:=al.alClient; r1:=trectangle.Create(pg); r2:=trectangle.Create(pg); r3:=trectangle.Create(pg); r4:=trectangle.Create(pg); r1.Parent:=pg;r1.Align:=al.alClient; r2.Parent:=pg;r2.Align:=al.alClient; r3.Parent:=pg;r3.Align:=al.alClient; r4.Parent:=pg;r4.Align:=al.alClient; t1:=ttext.Create(r1); if zap.tip<>'Лист' then Begin t1.Enabled:=false; t1.Text:='-'; End else Begin t1.text:=floattostr(zap.razmer.witdh); end; t2:=ttext.Create(r2);t2.text:=floattostr(zap.razmer.length); t3:=ttext.Create(form1);t3.Text:=floattostr(zap.razmer.kol); t4:=ttext.Create(form1);t4.Text:='X'; t1.Parent:=r1;t1.OnClick:=form1.CliskRazmerClick; t2.Parent:=r2;t2.OnClick:=form1.CliskRazmerClick; t3.Parent:=r3;t3.OnClick:=form1.CliskRazmerClick; t4.Parent:=r4;t4.OnClick:=form1.DeleteItemClick; t1.Align:=al.alClient; t2.Align:=al.alClient; t3.Align:=al.alClient; t4.Align:=al.alClient; form1.listbox1.InsertObject(form1.listbox1.Items.Count-1,item); t1.Name:='w'+IntToStr(item.Index); t2.Name:='l'+IntToStr(item.Index); t3.Name:='k'+IntToStr(item.Index); end; form1.listbox1.EndUpdate; end; Заранее спасибо!
    • От gresaggr
      Добрый день.
      IDE: Delphi 10.1 Berlin Update2
      OS: Windows 7/64 ->Android (тестировал на 4.4.4)
      Вопрос 1:
       
      Пытаюсь загрузить в Listbox файл с русскими словами: ListBox1.Items.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, 'test1.txt'));
      При запуске на устройстве выдает ошибку: No mapping for the Unicode character exists in the target multi-byte code page
      Файл пытался сохранить и в UTF-8, и в ANSI, и в Unicode - без разницы (после смены кодировки делал Deployment)
      Как можно это победить?
      Вопрос 2:
      Вставил напрямую в дизайн-моде список этих же слов (из файла вопрос1) в Listbox - при старте программа очень долго думает. Слов порядка 10000. Как-то можно это ускорить?


       


       


       
    • От M1shQa
      Есть один листбокс..) В общем парился я парился, так и не понял как запилить стиль по человечески для итемов в боксе и нашел кнопку Edit default Style. Нашел куда впилить TimageViewer и поставил ему свойство client. Все бы ничего, да вот размер итемов не статичен, а картинка не растягивается, к тому же pngшная картинка не отделяется от фона. Подскажите, как картинку растягивать в зависимости от длины и ширины итемов листбокса и как правильно юзать pngшные картинки (что бы они сохраняли прозрачность). Может я вообще не туда рою и нужно другими способами вставлять картинки под каждый item? Видел много гайдов под listview, но к сожалению мне нужно именно для бокса..
      ----
      п.с. что бы было проще: как нарисовать ровную плашку позади каждого элемента листбокс?
    • От chaplin.u@gmail.com
      У Мемо есть фича когда нажимаешь (тап по экрану) вылезает клавиатура для редактирования текста.
      Можно ли сделать такое-же с ListBox ? Тапаешь по итему и клавой исправляешь текст.
    • От M1shQa
      Всем утречка! Интересует вопрос кастмизации listbox в плане дизайна. Хотелось бы что бы плашки имели какой то другой цвет, рамку с обводкой и все на андроиде: в какую сторону рыть? Пилить стиль самому?
      Хотелось бы, что бы элементы в листбоксе были темно подсвечены и имели рамочку.. Стили ставил, а вот как поправить что-то в стиле пока не понял.
    • От Просто Проги
      Суть такова копаюсь в стилях, но не могу понять откуда идет наследования есть контейнер content в нем есть selection т,е выделенный элемент лист бокса , возможно ли создать стиль просто для итемов в листбоксе или это не делается через стиль?
    • От Dinkin
      Добрый день.
      Как по правому клики мыши.выделить итем в ListBox?. Проблема в том, что если у ListBox есть PoupMenu, оно перекрывает все события.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу