如何"refresh"TListBox?
How to "refresh" TListBox?
我正在创建一个显示账单号码的应用程序,就像您在麦当劳看到的那样。 POS 系统将账单号码发送到我的应用程序,这些号码显示在名为“ListBoxPrep”的 TListBox 中。然后,当 POS 系统向我的应用程序发送要删除的账单编号时,我的应用程序将其从“ListBoxPrep”中删除并将其添加到“ListBoxReady”。 POS 和我的应用程序之间的每次通信都是通过 TCP 连接完成的,我对此没有任何问题。
我面临的问题是,即使通过“pItem->Free();”将其删除,我仍然看到该数字仍然保留在“ListBoxPrep”中。 “pItem”是 TListBoxItem 的指针。我希望一旦我的应用程序收到来自 POS 的“删除信号”,尤其是在没有用户交互(例如单击面板等)的情况下,数字就会消失。我想使用 TTimer,但我不知道如何通过以下方式刷新“ListBoxPrep”本身。你有什么想法吗?任何建议将不胜感激。我正在使用 RAD Studio 10.4。
在我的应用程序收到来自 POS 的“删除信号”后,我仍然在右侧看到数字。他们应该消失。
我一点击“ListBoxPrep”,数字就消失了。
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();
}
TIdTCPServer
是多线程组件。它的 OnExecute
事件在工作线程的上下文中被调用。因此,它必须在访问 UI 控件时与主 UI 线程同步(顺便说一句,ShowMessage()
也是如此)。您可以为此使用 RTL 的 TThread::Synchronize()
(synchronous) or TThread::Queue()
(异步)方法。
此外,您不应该直接 Free()
'ing TListBoxItem
对象。您有所需项目的索引,您可以使用 ListBoxPrep->Items->Delete()
代替。
如果您使用的是 clang-based compilers 中的一种,请尝试类似这样的操作:
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,那么试试这个:
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);
}
或者这个:
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);
}
我修改了 IdTCPServerExecute
中的一些代码以删除一些编译错误。这是运行良好的代码。再次感谢您,Remy Lebeau
!
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);
}
}
我正在创建一个显示账单号码的应用程序,就像您在麦当劳看到的那样。 POS 系统将账单号码发送到我的应用程序,这些号码显示在名为“ListBoxPrep”的 TListBox 中。然后,当 POS 系统向我的应用程序发送要删除的账单编号时,我的应用程序将其从“ListBoxPrep”中删除并将其添加到“ListBoxReady”。 POS 和我的应用程序之间的每次通信都是通过 TCP 连接完成的,我对此没有任何问题。
我面临的问题是,即使通过“pItem->Free();”将其删除,我仍然看到该数字仍然保留在“ListBoxPrep”中。 “pItem”是 TListBoxItem 的指针。我希望一旦我的应用程序收到来自 POS 的“删除信号”,尤其是在没有用户交互(例如单击面板等)的情况下,数字就会消失。我想使用 TTimer,但我不知道如何通过以下方式刷新“ListBoxPrep”本身。你有什么想法吗?任何建议将不胜感激。我正在使用 RAD Studio 10.4。
在我的应用程序收到来自 POS 的“删除信号”后,我仍然在右侧看到数字。他们应该消失。
我一点击“ListBoxPrep”,数字就消失了。
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();
}
TIdTCPServer
是多线程组件。它的 OnExecute
事件在工作线程的上下文中被调用。因此,它必须在访问 UI 控件时与主 UI 线程同步(顺便说一句,ShowMessage()
也是如此)。您可以为此使用 RTL 的 TThread::Synchronize()
(synchronous) or TThread::Queue()
(异步)方法。
此外,您不应该直接 Free()
'ing TListBoxItem
对象。您有所需项目的索引,您可以使用 ListBoxPrep->Items->Delete()
代替。
如果您使用的是 clang-based compilers 中的一种,请尝试类似这样的操作:
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,那么试试这个:
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);
}
或者这个:
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);
}
我修改了 IdTCPServerExecute
中的一些代码以删除一些编译错误。这是运行良好的代码。再次感谢您,Remy Lebeau
!
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);
}
}