Recent

Author Topic: Listbox1.ItemIndex := -1 is not accepted  (Read 6017 times)

William Marshall

  • Jr. Member
  • **
  • Posts: 52
Listbox1.ItemIndex := -1 is not accepted
« on: November 20, 2014, 03:31:57 am »
     To represent a simplified portion of my program, I have a Listbox with several items, though not enough to fill the box - ie, there are a few lines of blank space below the last item.  There is also a button (btnClearSelections) and a label, as indicated in the code below:

Code: [Select]
procedure TfrmScratch.ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ListBox1.ItemIndex := ListBox1.GetIndexAtXY(X, Y);  // Why does this not return -1 in a blank space?
  lblItemIndex.Caption := 'ItemIndex = ' + IntToStr(ListBox1.ItemIndex);
end;

procedure TfrmScratch.btnClearSelectionsClick(Sender: TObject);
begin
  ListBox1.ItemIndex := -1;      // Highlighting is cleared, but ItemIndex is the last chosen index  - NOT -1
  lblItemIndex.Caption := 'ItemIndex = ' + IntToStr(ListBox1.ItemIndex);
end;
     My intention is to have a click in the blank space clear all highlighting in the Listbox and set its ItemIndex to -1.  Such a click does in fact remove the highlighting, but sets ItemIndex to the last item in the list, not -1, as can be seen in the label and the fact that pressing the up arrow key highlights the next-to-last item.  GetIndexAtXY, in the MouseDown event, is supposed to return -1 if no item can be found at X,Y.  Why doesn't the blank space count as "no item"?  How else could there be "no item"?
     More importantly, the direct assignment "ListBox1.ItemIndex := -1" in btnClearSelectionsClick seems to be completely ignored.  Highlighting is removed, but ItemIndex is still that of the last selected item.
     Are these bugs in TListbox, or am I not understanding what should be happening?
Lazarus 1.8.0; fpc 3.0.4; Windows 10

JZS

  • Full Member
  • ***
  • Posts: 194
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #1 on: November 20, 2014, 07:49:53 am »
Hi William,
Not sure which Laz & OS you are using but with Laz1.2.6 on Win 8 am using, all works just fine and return the correct ItemIndex.

Why doesn't the blank space count as "no item"?  How else could there be "no item"?

It depends on the perception of blank (Empty String).

The Items property of the TListBox is TStrings, which accommodates elements whenever you call "LB.Items.Add" by creating an extra element and update the counter index of the list no matter what string content you put in there.

I am sure you created those blank lines like this:
ListBox1.Items.Add('');

Isn't it? It means you have element in the list containing a value of string with zero length.

To achieve what you want, you can test if the elements contain blank first, as follows:
Code: [Select]
procedure TfrmScratch.ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  i:integer;
begin
  i:= ListBox1.GetIndexAtXY(X, Y);
  if (i <> -1) and (Trim(ListBox1.Items[i]) = '') then  // trim the spaces if required. up to you.
    i:= -1;

  ListBox1.ItemIndex:= i;

  lblItemIndex.Caption := 'ItemIndex = ' + IntToStr(ListBox1.ItemIndex);
end;

Regarding ClearSelections, it works fine here.
Try in a new project with nothing but the TButton and the TListBox to make sure of your result.
I use recent stable release

JZS

  • Full Member
  • ***
  • Posts: 194
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #2 on: November 20, 2014, 08:29:12 am »
BTW, how did you end up having empty lines in your list?

If avoidable, you shorten the list, and in between gaps, if you eliminate having blanks among your list's items.
I use recent stable release

William Marshall

  • Jr. Member
  • **
  • Posts: 52
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #3 on: November 20, 2014, 06:37:36 pm »
Hello JZS.  Thanks for your reply.  I'm using Lazarus version 1.2.4, FPC version 2.6.4, and Windows 7.  The listbox is high enough to hold maybe 20 items, but in this particular case I've only put 12 items into it.  There are NO blank lines, no gaps between items.  (The listbox displays the contents of one of several text files.  Some of the files are fairly large and fill the listbox, but others contain only a few lines.  Hence the empty space.  I suppose I could adjust the Listbox's height to the size of each text file, but that would be very distracting to the user and disrupt the design of the form.  The Listbox is the focal point of the form and has various controls around it.  I'd like to keep it a constant size.)  When I click anywhere in that space, whether it's just below the last item or at the bottom of the box, the ItemIndex returned by GetIndexAtXY is that of the last item (11 in this example), not the -1 that I was expecting.
     The other problem is that if I click on, say, the fourth item (ItemIndex = 3) and then click on btnClearSelections, where I specify ItemIndex := -1, the ItemIndex reported in the very next line is 3, NOT -1.  It is as if the first line in the Click event handler is simply ignored, except that the highlighting is removed.  (If I write "ItemIndex := 2" instead of -1, the third item is selected, as expected.  The problem is the -1.)
Lazarus 1.8.0; fpc 3.0.4; Windows 10

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #4 on: November 21, 2014, 01:50:22 am »
GetIndexAtXY is supposed to return the nearest item. Use ItemAtPos instead:
Code: [Select]
var
  pt: TPoint;
  i: Integer;
begin
  pt.x:=X;
  pt.y:=Y;
  i := ListBox1.ItemAtPos(Pt, True)
...
end;

I could not reproduce the second problem you mentioned.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #5 on: November 21, 2014, 11:36:48 am »
Your ListBox is MultiSelect, right? Then don't care about ItemIndex and check only Selected[].
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

William Marshall

  • Jr. Member
  • **
  • Posts: 52
Re: Listbox1.ItemIndex := -1 is not accepted
« Reply #6 on: November 22, 2014, 09:29:21 pm »
@ engkin: Thanks for your suggestion, but I'm getting the same behavior.

@ Blaazen: Yes, it is multiselect.  I apologize for not mentioning that.  I didn't think to turn it off.  It works OK when it's off, but I need
it on.

  Guess I'll have to accept this behavior or work around it.  Maybe it isn't as important as I thought it was.  Thanks, everyone.
Lazarus 1.8.0; fpc 3.0.4; Windows 10

 

TinyPortal © 2005-2018