【问题标题】:Clear ListView (firemonkey)清除 ListView (firemonkey)
【发布时间】:2018-11-04 19:05:18
【问题描述】:

我正在为具有按钮和 TListView 控件的 Windows 构建 FMX 应用程序。按钮代码只是用于填充 TListView 的 SQLite 数据库的查询。在某些情况下,查询需要 5-10 秒来处理。我想在单击按钮时立即清除 TListView(在查询完成并重新填充列表之前)。在第一个按钮代码中,我调用了 Clear 方法,但它不能立即工作:

ListView1->Clear();

旧数据保留在 TListView 控件中,直到查询完成并刷新它。如何强制列表为空 FIRST。

谢谢, 罗斯

已更新以清楚地显示正在发生的事情:

// 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();

【问题讨论】:

  • 您需要在问题中提供更多信息。现在有两个不同的答案,都是对未提供的信息的猜测。
  • 你试过在 ListView1.clear 之后调用 Application.ProcessMessages 吗?
  • 嗨 Federico - 解决了这个问题。我只是添加了 Application->ProcessMessages();在明确声明之后。谢谢! - 罗斯

标签: firemonkey c++builder


【解决方案1】:

一种可能的解决方案(使用 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;

【讨论】:

    【解决方案2】:

    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;
    

    【讨论】:

    • 不鼓励使用纯代码的答案。请单击编辑并添加一两段来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多