Очистить ListView (firemonkey) - PullRequest
       7

Очистить ListView (firemonkey)

0 голосов
/ 04 ноября 2018

Я создаю приложение FMX для Windows, в котором есть кнопка и элемент управления TListView. Код кнопки - это просто запрос базы данных SQLite, используемой для заполнения TListView. При некоторых обстоятельствах запрос обрабатывается в течение 5-10 секунд. Я хотел бы немедленно очистить TListView при нажатии кнопки (до того, как запрос будет выполнен и заполнен список). В первой части кода кнопки у меня есть вызов метода Clear, но он не работает сразу:

ListView1->Clear();

Старые данные остаются в элементе управления TListView до тех пор, пока запрос не завершит и не обновит его. Как я могу заставить список пустым в первую очередь.

спасибо, русс

ОБНОВЛЕНО, чтобы ясно показать, что происходит:

// This entire block of code below is inside a button click.
Form1->ListView1->Clear();
// This next line of code is what Frederico suggested - it works.
Application->ProcessMessages();

Form1->FDConnection1->Params->Values["Database"] = "T:\\mydata.db";
TFDQuery *query;
query = new TFDQuery(NULL);
query->Connection = Form1->FDConnection1;    // SQLite db
query->SQL->Text = "SELECT DISTINCT Project FROM Engineer_Updates WHERE Employee = '" + Form1->lblEngineerInitials->Text + "' ORDER BY Project";
query->Open();
  while(!query->Eof) {
    TListViewItem* itemHeader = Form1->ListView1->Items->Add();
    Form1->ListView1->BeginUpdate();
    itemHeader->Purpose = TListItemPurpose::Header;
    itemHeader->Text = query->FieldByName("Project")->AsString; // + " - " + query->FieldByName("Project WO")->AsString;  // "My Header";
    Form1->ListView1->EndUpdate();
        TFDQuery *query2;
        query2 = new TFDQuery(NULL);
            try {
            query2->Connection = Form1->FDConnection2;    // SQLite db
            query2->SQL->Text = "SELECT * FROM Engineer_Updates WHERE Project = '" + query->FieldByName("Project")->AsString + "' AND Employee = '" + Form1->lblEngineerInitials->Text + "'";
            query2->Open();
                 while (!query2->Eof) {
                  TListViewItem* item2Add = Form1->ListView1->Items->Add();
                  Form1->ListView1->BeginUpdate();
                  item2Add->Text = query2->FieldByName("Terminal/Equipment")->AsString + ", " + query2->FieldByName("Activity")->AsString;
                  mystring2 = query2->FieldByName("Terminal/Equipment")->AsString + ", " + query2->FieldByName("Activity")->AsString;
                  item2Add->Detail = mystring2;
                  Form1->ListView1->EndUpdate();
                  query2->Next();
                }
            }
            __finally {
              query2->Close();
              query2->DisposeOf();
            }
    query->Next();
    }
    query->Close();
    query->DisposeOf();

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Связывается ли TListView через BindSource? Если да, попробуйте очистить данные, используя отдельный поток, например, анонимный поток, и отключите набор данных в bindsource

BindSourceDB1.DataSet.Active := False;
TThread.CreateAnonymousThread(procedure ()
begin
    // delete data here using separated query
    TThread.Synchronize(nil, procedue ()
    begin
        BindSourceDB1.DataSet.Active := True;
    end);
end).Start;
0 голосов
/ 05 ноября 2018

Возможное решение (с использованием кода Delphi):

ListView1.Clear;
//eventually show a spinning wheel here, so the user knows something is going on.
ListView1.InvalidateRect(ListView1.BoundsRect); //<- might not be needed, try first without
TThread.ForceQueue(nil, procedure
  begin
    //execute your query here and fill the listview
    //stop the spinning wheel
  end;
...