TListBox - sprawdzenie ostatniego widzialnego itema

0

Witam, w jaki sposób mogę sprawdzić, czy kliknięto w ostatni widzialny item na liście? Algorytm ma sprawdzać, czy kliknięto np. w jeden z trzech ostatnich widzialnych itemów i jeżeli faktycznie kliknięto w niego, pokazać itemy poniżej klikniętego, czyli przesunąć suwak komponentu w dół o np. 5 pozycji (by pokazać 5 poniższych itemów). Trochę to namieszane, nie mam pojęcia jak sformułować zapytanie w google więc proszę Was o pomoc.

Np. klikając na item 13:

List1.png

algorytm sprawdza, czy są poniżej klikniętego np. 3 itemy i jeżeli tak, przesuwa suwak o trzy pozycję w dół - efekt:

List2.png

Czy macie jakiś pomysł na wykonanie tego? Bardzo proszę o pomoc. Pozdrawiam.

0

Nie wiem jak tam w Delphi, ale my tam w Lazarusie mamy TopIndex. Dodajesz do tego ilość itemków która się zmieści i masz ostatni indeks.
poza tym, temat nie taki do newbie...

0

Ok, postaram się coś wymodzić z TopIndex, sprawa nie jest aż taka trudna.

Jeżeli chodzi o temat - nie mam wyczucia co do tego, gdzie pisać temat. Zdaża się, że napiszę w Delphi, a userzy gniewają się, że temat zbyt banalny, by tam go poruszać.

W każdym razie - przetestuję i dam znać co i jak poszło. Dziękuję za wskazówkę, Pozdrawiam.

0

W załączniku masz program testowy; W nim masz algorytm do przesuwania suwaka i tyle itemów, ile chcesz pokazać; Tak naprawdę to nie jest przesuwanie suwaka, ale ustawianie właściwości ListBox.TopIndex w specjalny sposób tak, by wyglądało na przesuwanie; Masz w nim kilka warunków, w których jest sprawdzany ItemIndex oraz obliczane kilka rzeczy po to, by prawidłowo ocenić ilość itemów do pokazania;

Tutaj wklejam kod samego zdarzenia OnMouseDown, zaś w załączniku masz program, którym możesz testować napisany przeze mnie algorytm:

procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
const
  { LICZBA ITEMÓW DO POKAZANIA POD ZAZNACZONYM ITEMEM }
  iShowCount = 5;
var
  iIndex,
  iTop,
  iBottom,
  iCount,
  iShowCount,
  iPerScreen: Integer;
begin
  iIndex := ListBox1.ItemAtPos(Point(X, Y), True);

  case iIndex of
    -1: ListBox1.ItemIndex := -1;
  else
    ListBox1.ItemIndex := iIndex;
    ListBox1.Selected[iIndex] := True;

    { INDEKS PIERWSZEGO WIDOCZNEGO ITEMA NA LIŚCIE }
    iTop := ListBox1.TopIndex;
    { LICZBA ITEMÓW MIESZCZĄCYCH SIĘ W KOMPONENCIE }
    iPerScreen := ListBox1.Height div ListBox1.ItemHeight;
    { LICZBA WSZYSTKICH ITEMÓW }
    iCount := ListBox1.Items.Count;
    { INDEKS OSTATNIEGO WIDOCZNEGO ITEMA NA LIŚCIE }
    if iCount - iPerScreen > 0 then
      iBottom := iTop + iPerScreen - 1
    else
      iBottom := iCount - 1;

    { JEŻELI ITEMÓW JEST WIĘCEJ NIŻ POMIEŚCI KOMPONENT }
    if iCount > iPerScreen then
      { JEŻELI SUWAK NIE JEST NA SAMYM DOLE }
      if iBottom < iCount - 1 then
        { JEŻELI ITEMÓW POD INDEKSEM JEST MNIEJ NIŻ TYCH, KTÓRE CHCEMY POKAZAĆ }
        if iBottom - iIndex < iShowCount then
          if iCount - 1 - iIndex < 5 then
            { JEŻELI ITEMÓW POD INDEKSEM JEST MNIEJ, NIŻ TYCH KTÓRE CHCEMY POKAZAĆ }
            { PIERWSZY_WIDOCZNY := PIERWSZY_WIDOCZNY + ILOŚĆ_WSZYSTKICH - 1 - OSTATNI_WIDOCZNY }
            ListBox1.TopIndex := ListBox1.TopIndex + iCount - 1 - iBottom
          else
            { JEŻELI ITEMÓW JEST WIĘCEJ NIŻ TYCH, KTÓRE CHCEMY POKAZAĆ }
            { PIERWSZY_WIDOCZNY := PIERWSZY_WIDOCZNY + (ILOŚĆ_DO_POKAZANIA - (OSTATNI_WIDOCZNY - INDEKS)) }
            ListBox1.TopIndex := ListBox1.TopIndex + (iShowCount - (iBottom - iIndex));
  end;
end;

Procedura działa w 100% więc polecam sprawdzić jedynie zasadę działania; Można zamiast modyfikacji właściwości TopIndex posłużyć się metodą ListBox.ScrollBy(); Według uznania;

Pozdrawiam;

1 użytkowników online, w tym zalogowanych: 0, gości: 1