0

I'm Using Delphi Sydney 10.4 FMX, I have a ListView connected to a Database with liveBinding, ImageList that has 3 images.

In the ListView, I Have 3 Fields: Image, Expiry, Domain.

The Expiry and Domain are filled from the Database, but the image I want to show depends on the date, example :

Expiry = date of today or before today: I want to show imageindex 0

Expiry = from Tomorrow until 30 days from Today: I want to show imageindex 1

Expiry = 31 Days Later from today: I want to show imageindex 2

procedure TForm1.DomainsListViewUpdateObjects(const Sender: TObject;
  const AItem: TListViewItem);
begin
  var DT : TDateTime;
  DT := Now;
  if DomainsListView.Items[DomainsListView.ItemIndex].Data['expiry'].AsString < datetostr(DT+30) then
    DomainsListView.Items[DomainsListView.ItemIndex].Data['image'] := 1
  else if DomainsListView.Items[DomainsListView.ItemIndex].Data['expiry'].AsString < DateToStr(DT) then
    DomainsListView.Items[DomainsListView.ItemIndex].Data['image'] := 0
  else if DomainsListView.Items[DomainsListView.ItemIndex].Data['expiry'].AsString > DateToStr(DT+31) then
    DomainsListView.Items[DomainsListView.ItemIndex].Data['image'] := 2
end;

I used this code, but does not works correctly

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
MrSiMo
  • 101
  • 7

1 Answers1

3

You are comparing String values, which doesn't work to compare dates. You should be comparing TDateTime values instead, as well as paying more attention to the order of your comparisons.

Try something more like this instead:

uses
  ..., System.SysUtils, System.DateUtils;

procedure TForm1.DomainsListViewUpdateObjects(const Sender: TObject;
  const AItem: TListViewItem);
begin
  var Item: TListViewItem := DomainsListView.Items[DomainsListView.ItemIndex]; // or: DomainsListView.Selected
  var dtToday: TDateTime := System.DateUtils.Today;
  var dtExpiry: TDateTime := System.SysUtils.StrToDate(Item.Data['expiry'].AsString);
  if dtExpiry <= dtToday then
    Item.Data['image'] := 0 
  else if dtExpiry < (dtToday+31) then
    Item.Data['image'] := 1
  else
    Item.Data['image'] := 2;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • i changed it by System.DateUtils.Today and it works thank you Remy – MrSiMo Apr 12 '22 at 03:08
  • this update didn't work: `E2003 Undeclared identifier: 'Data' E2250 There is no overloaded version of 'StrToDate' that can be called with these arguments` – MrSiMo Apr 13 '22 at 00:51
  • @MrSiMo Try declaring `Item` as `TListViewItem` instead of `TListItem`. You can ignore the `StrToDate()` error, it is just a side effect of the 1st error and will go away when the 1st error is fixed. – Remy Lebeau Apr 13 '22 at 01:19
  • the images show perfectly, but I have a problem, when I run: `fdquery.insert; ` i got error : `'' is not a valide date and time.` 3 times. how can i solve this problem? – MrSiMo Apr 13 '22 at 20:05
  • @MrSiMo Obviously, you have to check your input before converting it. Sounds like the ListView is creating a new item before the data backing that item is ready. For example, try adding this check before the call to `StrToDate()`: `var sExpiry := Item.Data['expiry'].AsString; if sExpiry = '' then Exit;` – Remy Lebeau Apr 13 '22 at 20:27