StringGrid i scrolling zawartości

0

Witam

Szukałem info na ten temat, ale nie znalazłem. Czy ktoś z Was może zetknął się kiedyś z kontrolą scrollingu ? Chodzi o to, że jak wyświetli się ScrollBar-Vertical i przewijam nim zawartość StringGrid1 to jest jak w starych wersjach Win - okienko nie przewiaja się w locie tylko dopiero po puszczeniu klawisza (jak w Win3.11). Czy da się przewijać StringGrida płynnie pod Delphi7 ?

No i czy można ustawić jego widok - tj, np: na ostatnie wiersze a nie początkowe - może jest jakaś komenda na zaznaczenie (obramowanie) komórki i wtedy widok(i pasek) się przesunie na wybraną pozycję ?

0

Dopisz jeszcze łaskawie czy chodzi o Delphi (a jeśli tak to w której wersji) czy o Lazarusa; I jaki masz system.

0

Napisałem w poście w postaci linijki: Czy da się przewijać StringGrida płynnie pod Delphi7 ?

OS: Win10

4

@stdstringclass - Wystarczy zaznaczyć enum goThumbTracking we właściwości Options i już komponent odświeżany jest "na żywo";

Co do drugiego pytania - pierwsza widoczna kolumna siedzi we właściwości LeftCol - nadanie jej wartości zmienia widok; Do zmiany pierwszego widocznego wiersza jest właściwość TopRow.

0

scrolling działa, dzięki.

StringGrid1.LeftCol jak ustawiam na StringGrid1.RowCount to się zamazują wszystkie komórki: )

0

A co ma pierwsza widoczna kolumna do liczby wierszy? No raczej nic...

Aby zmienić widok, tak aby widzieć wszystkie ostatnie kolumny, wystarczy skorzystać z odpowiednich właściwości:

StringGrid.LeftCol := StringGrid.ColCount - StringGrid.VisibleColCount;

Jeśli wszystkie kolumny będą widoczne w komponencie (czyli suma szerokości wszystkich kolumn będzie mniejsza od szerokości całego komponentu) to powyższy kod nadal będzie działać prawidłowo.

0

furious programming
A co ma pierwsza widoczna kolumna do liczby wierszy? No raczej nic...

No możliwe, że nic nie ma, ale wcześniej napisałeś: pierwsza widoczna kolumna siedzi we właściwości LeftCol - nadanie jej wartości zmienia widok;

To zmieniłem jej wartość, akurat w moim przypadku na ilość wierszy. Faktycznie nie wspomniałem o tym, że szerokości kolumn są różne (wiersze takie same) bo nie sądziłem, że scrolling (czy widok) może brać ten parametr pod uwagę. W końcu pasek ScrollBar_Vertical pojawia się niezależnie od szerokości kolumn i również działa poprawnie dla dowolnych rozmiarów wierszy czy kolumn.

Widzę, że sporo z tym zachodu. Myślałem, że istnieje coś w rodzaju komendy:

StringGrid1.ustaw_Komórkę := wartość liczbowa

Bo czasami zaznaczenie to taki przerywany kwadracik na około CELL a czasem wypełnienie solid.

Panowie z tego co widzę LeftCol=5 przylepia 5tą kolumnę do 1szej a reszta znika.
Mi chodzi o inny efekt kiedy jest przeciążenie okienka wierszami i mamy ich np: 100, które trzeba przewijać. Problem teraz w tym jak podwinąć wiersze do góry by np: pokazane były wiersze od od 80 do 100(koniec) a nie początek, który mieści po 20 wierszy i wyświetla je od 1 do 20...

0

No możliwe, że nic nie ma, ale wcześniej napisałeś: pierwsza widoczna kolumna siedzi we właściwości LeftCol - nadanie jej wartości zmienia widok;

No bo zmienia, tyle że trzeba jej nadać indeks istniejącej kolumny, a nie indeks nieistniejącego wiersza :]

Faktycznie nie wspomniałem o tym, że szerokości kolumn są różne (wiersze takie same) bo nie sądziłem, że scrolling (czy widok) może brać ten parametr pod uwagę.

Miło wiedzieć, że na próżno się odpowiadało; BTW - przewijanie działa "płynnie" na zasadzie skoków, które wynoszą tyle, ile wynosi szerokość kolumny (HScroll) lub wysokość wiersza (VScroll);


W takim razie - skoro szerokości kolumn mogą być różne - niżej podaję rozwiązanie dla komponentu, który może zawierać kolumny o różnych szerokościach; Brane pod uwagę jest kilka elementów - liczba stałych (fixed) kolumn, które zawsze widoczne są w komponencie, grubość linii siatki oraz szerokość klienta, czyli szerokość wnętrza komponentu, bez szerokości pionowego paska przesuwu;

procedure TForm1.btnShowLastColumnsClick(Sender: TObject);
var
  intGridLineWidth, intColWidths, intCurrColWidth, intColIdx: Integer;
begin
  if Grid.ColCount - Grid.FixedCols > 0 then
  begin
    intGridLineWidth := Grid.GridLineWidth;
    intColWidths := 0;

    for intColIdx := 0 to Grid.FixedCols - 1 do
      Inc(intColWidths, Grid.ColWidths[intColIdx] + intGridLineWidth);

    if intColWidths <= Grid.ClientWidth then
    begin
      intColIdx := Grid.ColCount - 1;
      Inc(intColWidths, Grid.ColWidths[intColIdx] + intGridLineWidth);

      while (intColIdx >= Grid.FixedCols) and (intColWidths < Grid.ClientWidth) do
      begin
        intCurrColWidth := Grid.ColWidths[intColIdx - 1] + intGridLineWidth;

        if intColWidths + intCurrColWidth <= Grid.ClientWidth then
        begin
          Inc(intColWidths, intCurrColWidth);
          Dec(intColIdx);
        end
        else
          Break;
      end;

      Grid.LeftCol := intColIdx;
    end;
  end;
end;

Pokrótce wytłumaczę jak to działa - pierwszy warunek sprawdza, czy oprócz FixedCols są jeszcze jakieś kolumny - jeżeli nie to reszta kodu jest pomijana; Następnie pobierana jest grubość siatki; Kolejny krok to zliczenie szerokości wszystkich FixedCols, razem z GridLineWidth; Drugi warunek sprawdza, czy obliczona szerokość jest mniejsza od dostępnej szerokości komponentu (bez pionowego scrollbara) i jeśli tak - idziemy dalej; Kolejnym krokiem jest pobranie indeksu ostatniej kolumny oraz zwiększenie łącznej szerokości (intColWidths) o szerokość ostatniej kolumny + grubość linii siatki; Ostatni krok to pętla While - w niej sumowane są szerokości kolumn od końca (oprócz ostatniej) do momentu, aż szerokość kolumny o indeksie intColIdx dodana do łącznej szerokości będzie większa od ClientWidth; Jeśli będzie większa, szerokość tej kolumny nie zostanie dodana, a indeks intColIdx nie zostanie zdekrementowany; Ostatnim krokiem jest wpisanie wartości zmiennej intColIdx do właściwości LeftCol;

W testach powyższy kod wypada idealnie (co do piksela), jednak możliwe, że coś przeoczyłem; W razie, gdyby coś jeszcze nie było zabezpieczone - można pododawać warunki; W załączniku GridCols.zip aplikacja do przetestowania - plik wykonywalny, który według testów działa dobrze, a także źródła do skompilowania programu pod Delphi7;

Panowie z tego co widzę LeftCol=5 przylepia 5tą kolumnę do 1szej a reszta znika.

Nic podobnego - FixedCols i FixedRows zawsze są widoczne, natomiast LeftCol oznacza pierwszą widoczną kolumnę ze standardowo białymi komórkami, zaraz obok ostatniej FixedCols;

Mi chodzi o inny efekt kiedy jest przeciążenie okienka wierszami i mamy ich np: 100, które trzeba przewijać. Problem teraz w tym jak podwinąć wiersze do góry by np: pokazane były wiersze od od 80 do 100(koniec) a nie początek, który mieści po 20 wierszy i wyświetla je od 1 do 20...

Napisz to jeszcze raz, bo Bóg jeden wie co masz na myśli...

0
furious programming napisał(a)

Napisz to jeszcze raz, bo Bóg jeden wie co masz na myśli...

Powiedzmy, że na Form1 utworzysz StringGrid1, który domyślnie wyświetla 20 wierszy na raz (Rows). Jak dodasz 21 to pojawia się ScrollBar bo na raz mieści się tylko 20 rekordów (wierszy) w okienku. Teraz jeśli masz sytuację, że StringGrid1 ma 100 wierszy to masz 5 bloków (5widoków) po 20 wyświetlonych rekordów.

Podsumowując: czy można wywołać efekt jakbym klikał w strzałeczki scrollujące na ScrollBar_Vertical ? Np:, że jak podam wiersz 70 to mi się on wyśrodkuje na StringGrid w ten sam sposób jakbym użył paska przewijania po prawej.

1

Podsumowując: czy można wywołać efekt jakbym klikał w strzałeczki scrollujące na ScrollBar_Vertical ? Np:, że jak podam wiersz 70 to mi się on wyśrodkuje na StringGrid w ten sam sposób jakbym użył paska przewijania po prawej.

No można - do tego właśnie są właściwości LeftCol i TopRow; Trzeba im tylko podać odpowiednie wartości.

0

o właśnie StringGrid1.TopRow jest tym co mi trzeba było.

Ciekawe są tylko proporcje. Mam 52 wiersze (na raz wyświetlane 20) i moje TopRow przyjmuje wartości do 31. Jak przyjmie wartość 31 to widać dokładnie sam koniec tabeli. Ciekawy zakres (1..31) :)

1
31 + {TopRow} + 20 {VisibleRowCount} = 51 {RowCount - 1}

Ja nie wiem czy Ty ogarniasz język angielski... TopRow to górny wiersz, a raczej jego indeks; Jeśli ma być wyświetlonych dwadzieścia ostatnich wierszy, to ich indeksy są równe 31 .. 51, a dla pierwszych dwudziestu 0 .. 19; Podobnie dla kolumn; Nieco wtrąca się FixedCols i FixedRows, czyli te "twarde" kolumny i wiersze, które zawsze są widoczne, dlatego musiałem je wziąć pod uwagę pisząc ten kod; Jednak wszystko jest logicznie przemyślane i zaimplementowane - tu nie ma nic nadzwyczajnego;

A tak w ogóle to kod który podałem działa dla kolumn jakbyś nie zauważył, więc trzeba go zmodyfikować, tak aby działał dla wierszy, ale to już zadanie dla Ciebie, coby gotowców nie rzucać; Przy czym jeśli wysokość wszystkich wierszy jest taka sama to można to dużo łatwiej wykonać.

0

Tak jak już wiem, że topRow to pierwszy wyświetlany wiersz to już sobie poradzę. Teraz już wiem wszystko co chciałem wiedzieć. Dzięki serdeczne!

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