Перейти к содержанию
  • 0
Billy Bones

Виртуальный ListBox в FireMonkey (FMX)

Вопросы

У управляющего элемента TListBox, в библиотеке VCL, есть возможность, работать в виртуальном режиме ( Style = lbVirtual ), когда данные, для элементов списка, поставляет метод, связанный с событием OnData:

Спойлер

Unit main;

Interface

Uses
    System.Classes,
    Vcl.Forms,
    Vcl.Controls,
    Vcl.StdCtrls;

Type
    TfmMain = class(TForm)
        lbItems: TListBox;
        procedure lbItemsData(Control: TWinControl; Index: Integer; var Data : string);
        procedure FormShow(Sender: TObject);
    public
        constructor Create(AOwner : TComponent); override;
    end;

Var
    fmMain : TfmMain;

Implementation

Uses
    System.SysUtils;

{$R *.dfm}

Const
    MaxLines = 65536;

    {--------------------------------------------------------------------------}
    constructor TfmMain.Create(AOwner : TComponent);
    begin
        inherited Create(AOwner);
        lbItems.Count := MaxLines;
    end;

    {--------------------------------------------------------------------------}
    procedure TfmMain.FormShow(Sender: TObject);
    begin
        lbItems.ItemIndex := MaxLines - 1;
    end;

    {--------------------------------------------------------------------------}
    procedure TfmMain.lbItemsData(    Control : TWinControl;
                                      Index   : Integer;
                                  var Data    : string);
    begin
        Data := 'Item ' + IntToStr(Index);
    end;
End.

 

Есть ли что-нибудь похожее в FireMonkey (FMX) ?

Или придется для каждого элемента списка создавать объект класса TListBoxItem ?

Попытка создать, таким образом, ListBox на 65536 элементов, приводит к диким расходам ОП - 248 MB:

Спойлер

Const
    MaxLines = 65536;

    procedure TfmMain.btAddItemsClick(Sender: TObject);
    var
        I      : Integer;
        M      : TListBoxItem;
        T0, T1 : TDateTime;
    begin
        T0 := Now;
        lbItems.BeginUpdate;
        try
            for I := 0 to MaxLines - 1 do
                begin
                    M := TListBoxItem.Create(nil);
                    M.Parent := lbItems;
                    M.Text   := 'Item ' + IntToStr(I);
                end;
        finally
            lbItems.EndUpdate;
        end;
        T1 := Now;
        edTime.Text := IntToStr(SecondsBetween(T0, T1));
    end;

 

 

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


Ссылка на сообщение

Рекомендуемые сообщения

  • 0

вроде уж везде написали что ListBox не предназначен для 20+ элементов. используйте ListView 

https://www.youtube.com/watch?v=XRj3qjUjBlc

для облегчения нелегкой работки можно посмотреть тут 

http://fire-monkey.ru/topic/5519-фреймворк-для-стандартного-listview/#comment-34912

 

ну и да, 50000+ элементов это несколько трешовый UI

Отредактировал krapotkin

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


Ссылка на сообщение
  • 0
15 часов назад, krapotkin сказал:

вроде уж везде написали что ListBox не предназначен для 20+ элементов. используйте ListView 

https://www.youtube.com/watch?v=XRj3qjUjBlc

Спасибо за совет, я не видел данного видео. ListView существенно экономнее расходует ОП, но вопрос был о том, имеется ли в FMX функционал, подобный виртуальному ListBox из VCL.

Я посмотрел исходные коды для ListView и наверное, я сумею изобразить, что-то похожее, на виртуальный ListBox, установив свойство Adapter, у ListView, на определенный мной, класс - наследник от IListViewAdapter.

Но увиденное в исходных кодах, немного настораживает, т.к. ListView, в некоторых своих методах, обращается, одновременно, и к элементу номер X, и к элементу номер Y - т.е. предполагается, что в данный момент времени, они оба существуют (Скорее всего, предполагается, что существуют элементы в диапазоне от 0 до Adapter.Count ). Я же, хотел избежать, выделения памяти, для структуры из элементов TListViewItem, содержащей Adapter.Count элементов. Именно этим свойством обладает виртуальный ListBox из VCL.

15 часов назад, krapotkin сказал:

ну и да, 50000+ элементов это несколько трешовый UI

Естественно, столько элементов не будет, но потенциально, может быть сколько угодно. И нужно быть к этому готовым.

Данный функционал, нужен для настольного приложения под Linux. В Windows хватает и VCL. На смартфонах приложение разворачивать не планирутся никогда.

Отредактировал Billy Bones

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


Ссылка на сообщение
  • 0

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

ListView всего лишь не создает ненужные компоненты для каждого item, как это делает ListBox, но данные для своего отображения может запросить любые в любой момент. В принципе, это достаточная виртуализация imho

 

Кроме того для десктопа пара тысяч элементов в ListView особых проблем обычно не вызывает

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


Ссылка на сообщение
  • 0
2 минуты назад, krapotkin сказал:

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

Это уже понятно :) .

2 минуты назад, krapotkin сказал:

Кроме того для десктопа пара тысяч элементов в ListView особых проблем обычно не вызывает

Тормозить, при изменении размеров окна (и вместе с ним ListView), начинает уже от 1000, а виртуалный ListBox в VCL и при 65535 не тормозит !

Очень не хотелось свои компоненты писать !

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


Ссылка на сообщение
  • 0

можно попробовать что то типа TStringGrid и в его событии OnDrawColumnCell прорисовывать то что надо вручную.

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


Ссылка на сообщение

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Последние посетители   0 пользователей онлайн

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

×
×
  • Создать...