首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何“刷新”TListBox?

如何“刷新”TListBox?
EN

Stack Overflow用户
提问于 2021-05-12 23:59:55
回答 2查看 93关注 0票数 0

我正在创建一个显示账单号码的应用程序,就像你在麦当劳看到的一样。POS机系统将账单号码发送到我的应用程序中,这些号码显示在一个名为"ListBoxPrep“的TListBox中。然后,当POS机系统向我的应用程序发送要删除的账单编号时,我的应用程序会从"ListBoxPrep“中删除它,并将其添加到"ListBoxReady”中。POS和我的应用程序之间的每一次通信都是通过TCP连接完成的,我对此没有任何问题。

我面临的问题是,即使在通过“pItem->ListBoxPrep();”将其删除后,我仍然看到数字保留在"ListBoxPrep“中。"pItem“是TListBoxItem的指针。我希望一旦我的应用程序从POS机接收到“删除信号”,这些数字就会消失,特别是没有用户的干预,比如点击面板等。我想使用TTimer,但我不知道如何让"ListBoxPrep“刷新。你有这样做的想法吗?任何建议都将不胜感激。我使用的是RAD Studio 10.4。

在我的应用程序收到来自POS的“删除信号”后,我仍然在右侧看到数字。他们应该消失了。

我一点击"ListBoxPrep",数字就消失了。

代码语言:javascript
复制
void __fastcall TForm1::IdTCPServerExecute(TIdContext *AContext)
{
    //We receive data: POS --> Screen(PC)
    String sentDataFromPOS = AContext->Connection->Socket->ReadLn();

    if(sentDataFromPOS .IsEmpty())
    {
        ShowMessage("Data sent from POS is empty!");
        return;
    }

    // 1. Find an order number to move to the right (prep -> ready)
    int indexOrderToRemove = ListBoxPrep->Items->IndexOf(sentDataFromPOS);

    // 2. Add the order number to the "Ready list"
    addNumberToReady(sentDataFromPOS);

    // 3. Remove the order from the "Prep list"
    ListBoxPrep->BeginUpdate();
    TListBoxItem* pItem = ListBoxPrep->ItemByIndex(indexOrderToRemove);
    pItem->Free(); // HERE I have a problem

    // test: To refresh the screen
    LayoutLeft->Visible = false;
    LayoutLeft->Visible = true;

    /*
    ListBoxPrep->Enabled = false;
    ListBoxPrep->Visible = false;
    ListBoxPrep->Enabled = true;
    ListBoxPrep->Visible = true;
    ListBoxPrep->Repaint();
    */
    ListBoxPrep->EndUpdate();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-13 01:39:22

TIdTCPServer是一个多线程组件。它的OnExecute事件在工作线程的上下文中调用。因此,在访问UI控件时,它必须与主UI线程同步(这也适用于ShowMessage(),BTW)。为此,可以使用RTL的TThread::Synchronize() (同步)或TThread::Queue() (异步)方法。

另外,你不应该直接Free() TListBoxItem对象,你有了所需项目的索引,你可以使用ListBoxPrep->Items->Delete()

如果您使用的是其中一种clang-based compilers,请尝试更多类似以下内容的方法:

代码语言:javascript
复制
void __fastcall TForm1::IdTCPServerExecute(TIdContext *AContext)
{
    //We receive data: POS --> Screen(PC)
    String sentDataFromPOS = AContext->Connection->Socket->ReadLn();

    if (sentDataFromPOS.IsEmpty())
    {
        TThread::Synchronize(nullptr,
            [](){ ShowMessage("Data sent from POS is empty!"); }
        );
        return;
    }

    TThread::Queue(nullptr, // or Synchronize(), your choice...
        [=, this](){ this->orderIsReady(sentDataFromPOS); }
    );
}

void __fastcall TForm1::orderIsReady(String orderNumber)
{
    // 1. Find an order number to move to the right (prep -> ready)
    int indexOrderToRemove = ListBoxPrep->Items->IndexOf(orderNumber);

    // 2. Add the order number to the "Ready list"
    addNumberToReady(orderNumber);

    // 3. Remove the order from the "Prep list"
    if (indexOrderToRemove != -1)
        ListBoxPrep->Items->Delete(indexOrderToRemove);
}

另一方面,如果您使用的是"classic" Borland compiler,请尝试执行以下操作:

代码语言:javascript
复制
struct orderHelper
{
    String orderNumber;

    orderHelper(const String &orderNumber)
        : orderNumber(orderNumber)
    {
    }

    void __fastcall orderIsReady()
    {
        Form1->orderIsReady(orderNumber);
    }
};

void __fastcall TForm1::orderIsEmpty()
{
    ShowMessage("Data sent from POS is empty!");
}

void __fastcall TForm1::IdTCPServerExecute(TIdContext *AContext)
{
    //We receive data: POS --> Screen(PC)

    String sentDataFromPOS = AContext->Connection->Socket->ReadLn();

    if (sentDataFromPOS.IsEmpty())
    {
        TThread::Synchronize(NULL, &orderIsEmpty);
        return;
    }

    orderHelper helper(sentDataFromPOS);
    TThread::Synchronize(NULL, &(helper.orderIsReady));
}

void __fastcall TForm1::orderIsReady(String orderNumber)
{
    // 1. Find an order number to move to the right (prep -> ready)
    int indexOrderToRemove = ListBoxPrep->Items->IndexOf(orderNumber);

    // 2. Add the order number to the "Ready list"
    addNumberToReady(orderNumber);

    // 3. Remove the order from the "Prep list"
    if (indexOrderToRemove != -1)
        ListBoxPrep->Items->Delete(indexOrderToRemove);
}

或者这样:

代码语言:javascript
复制
struct orderHelper
{
    String orderNumber;

    orderHelper(const String &orderNumber)
        : orderNumber(orderNumber)
    {
    }

    void __fastcall orderIsReady()
    {
        try {
            Form1->orderIsReady(orderNumber);
        } __finally {
            delete this;
        }
    }
};

void __fastcall TForm1::orderIsEmpty()
{
    ShowMessage("Data sent from POS is empty!");
}

void __fastcall TForm1::IdTCPServerExecute(TIdContext *AContext)
{
    //We receive data: POS --> Screen(PC)

    String sentDataFromPOS = AContext->Connection->Socket->ReadLn();

    if (sentDataFromPOS.IsEmpty())
    {
        TThread::Synchronize(NULL, &orderIsEmpty);
        return;
    }

    orderHelper *helper = new orderHelper(sentDataFromPOS);
    TThread::Queue(NULL, &(helper->orderIsReady));
}

void __fastcall TForm1::orderIsReady(String orderNumber)
{
    // 1. Find an order number to move to the right (prep -> ready)
    int indexOrderToRemove = ListBoxPrep->Items->IndexOf(orderNumber);

    // 2. Add the order number to the "Ready list"
    addNumberToReady(orderNumber);

    // 3. Remove the order from the "Prep list"
    if (indexOrderToRemove != -1)
        ListBoxPrep->Items->Delete(indexOrderToRemove);
}
票数 2
EN

Stack Overflow用户

发布于 2021-05-13 02:47:49

我修改了IdTCPServerExecute中的一些代码,以消除一些编译错误。下面是运行良好的代码。再次感谢你,Remy Lebeau

代码语言:javascript
复制
void __fastcall TForm1::IdTCPServerExecute(TIdContext *AContext)
{
    //We receive data: POS --> Screen(PC)
    String sentDataFromPos = AContext->Connection->Socket->ReadLn();

    // test
    //sentDataFromPos = "";

    if(sentDataFromPos.IsEmpty())
    {
        TThread::Synchronize(nullptr,
            [=](){ ShowMessage("Data sent from POS is empty!"); }
        );

        return;
    }

    TThread::Synchronize(nullptr, 
// Queue doesn't make the numbers disappear. It doesn't display them at right side either .
        [&, this]()
        {
            this->orderIsReady(sentDataFromPos);
        }
    );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::orderIsReady(String orderNumber)
{
    // 1. Find an order to move to the right (prep -> ready)
    int indexOrderToRemove = ListBoxPrep->Items->IndexOf(orderNumber);

    // 2. Add an order of the same order number to the "Ready list"
    addNumberToReady(orderNumber);

    // 3. Remove the order from the "Prep list"
    if(indexOrderToRemove != -1)
    {
        ListBoxPrep->Items->Delete(indexOrderToRemove);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67507117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档