• 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 строк процедура?

 

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

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

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

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

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


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

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

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

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

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

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

Войти

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

Войти


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

    • От 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, оно перекрывает все события.
    • От Просто Проги
      Собственно вопрос всё ещё копаю в сторону listbox сделал такой listbox
        var
      listitem:Tlistboxitem;
      listimg1:Timage;
      listlabel1:Tlabel;
      listLayout:Tlayout;
      progres:TProgressBar;
      but:TSpeedButton;
      begin
      listitem:=TListBoxItem.Create(ListBox1);
       listitem.Parent:=ListBox1;
       listitem.Height:=50;
        listimg1:=TImage.Create(listitem);
        listimg1.Parent:=listitem;
        listimg1.Width:=50;
        listimg1.Height:=50;
        listimg1.Align:=TAlignLayout.Left;
        listimg1.Bitmap:=Image1.Bitmap;
        //
          but:=TSpeedButton.Create(listitem);
          but.Parent:=listitem;
          but.StyleLookup:='myControl';
          but.Align:=TAlignLayout.Right;
            listLayout:=TLayout.Create(listitem);
            listLayout.Parent:=listitem;
            listLayout.Align:=TAlignLayout.Client;
             listlabel1:=TLabel.Create(listLayout);
             listlabel1.Parent:=listLayout;
             listlabel1.Align:=TAlignLayout.Top;
             listlabel1.Height:=25;
             listlabel1.StyledSettings:=[TStyledSetting.Family,TStyledSetting.Style];
             listlabel1.TextSettings.Font.Size:=12;
             listlabel1.TextSettings.FontColor:=TAlphaColorRec.White;
             listlabel1.Text:='event';
            end;
        finally
            ListBox1.EndUpdate;
      как получить доступ к кнопке в созданном listbox ? или хотя бы  как получить текст в  listlabel1 в выбранном item.
      поидее должно работать item.selected но что то опять не работает или я туплю)
    • От Просто Проги
      Привет всем может кто подскажет что не так создаю процедуру для добавления
      var
       item: TMetropolisUIListBoxItem;
      begin
      item :=TMetropolisUIListBoxItem.Create(Form1);
      item.Title:='Title';
      item.SubTitle:='sub';
      item.Description:=dua;
      ListBox1.AddObject(item);
      end;
      Всё добавляется,но когда я пытаюсь закрыть программу то падает ошибка
      procedure TObject.FreeInstance;
      begin
        CleanupInstance;
      _FreeMem(Pointer(Self));// на этой строке ошибка
      end;
      Как я понял что ошибка связана с памятью как можно правильно освободить память? и избавиться от этой ошибки )
    • От Akromd
      Добрый день, не знаю уместен ли вопрос в этой ветке, но тем не менее.
      Задача следующая: есть ListBox на форме, с помощью стилей создан специальный ListItem с множеством edit'ов  и т.д. При загрузке excel файла все это заполняется и выводится.
      Так вот, все это работает хорошо, до тех пор пока не начинаешь прокручивать - через некоторое время вылетает ошибка
      Собственно вопрос - По каким причинам она возникает и как ее можно исправить?
      проект выложил, подгрузка из файла - по умолчанию путь к файлу - C:\Users\Admin\Documents\Embarcadero\Studio\Projects\.
      Projects.rar
  • Последние посетители   0 пользователей онлайн

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