TListView i OwnerDraw - Galeria

0

Witam wszystkich, mam mały problem z komponentem TListView i OwnerDraw.

W tym komponencie będzie dokładnie 10 itemów (stale i niezmiennie). Chciałbym je narysować samemu w dwóch wierszach po 5 itemów.

Niestety nie wiem w jaki ma być styl widoku komponentu (vsIcon itd...) i w którym zdarzeniu odbywać się ma malowanie.

Próbowałem na wszystkich ViewStyle, ale nawet gdy miałem ustawioną właściwość OwnerDraw na True, nie mogłem samemu malować itemów.

Każdy item ma mieć wymiary przykładowo 100x100 pikseli (czyli całość ma mieć wysokość 200 pikseli i szerokość 500 pikseli).

Grafika do każdego itemu będzie wczytywana ze specjalnie przygotowanej tablicy przechowującej obrazy typu bmp.

Co do samego rysowania nie mam żadnych pytań, wszystko co mi jest potrzebne do tego wiem. Sprawa tyczy się tylko ustawienia szerokości i wysokości każdego itemu oraz pozbycia się ewentualnie pokazującego się pola z napisem (czyli Caption w każdym itemie).

Sprawdzałem jak to wygląda w widoku vsIcon, ale tak jak to jest w systemie, pokazuje się pod grafiką napis (tak jak w systemie nazwa pliku). Chcę się jej pozbyć i samodzielnie namalować calutki item tak, jak to można zrobić w zwykłym TListBox.

Wie ktoś jak to zrobić? Bardzo proszę o pomoc.
Dziękuję z góry i pozdrawiam.

EDIT: Na szybkiego narysowałem w Paint jak to by miało wyglądać (z XPManifest na formie - niebieska ramka to ramka komponentu TListView):

http://imageshack.us/photo/my-images/854/tlistview.png/

0

Nie bardzo wiem co chcesz osiągnąć, ale to co narysowałeś sam bardziej pasuje mi do StringGrida, zobacz sobie kod z załacznika do tego posta jak koloruje komórki kalendarza, ale mogąć operowac na Canvasie możesz narysować w okolicach tych komórek dowolną grafikę wczytaną na przykład z odpowiednich rozmiarów bitmapy.

0
Olesio napisał(a)

ale to co narysowałeś sam bardziej pasuje mi do StringGrida

Wiem, że to najlepiej nie wygląda, ale nie chodzi mi o TStringGrid, tylko o TListView. Na tym rysunku czarne linie określają granice każdego z itemów. To jest tylko przykład, w programie nie będzie tych linii. Chciałbym zrobić tak, by w komponencie TListView itemy były w pięciu kolumnach i dwóch wierszach. Granice każdego itemu określają czarne linie na rysunku. To tak jak w TListBox, powierzchnia itemu (nie wiem jak to określić - chodzi mi o parametr Rect) jest na całą szerokość komponentu, chyba, że jest więcej niż jedna kolumna.

Koniecznie ma to być komponent TListView. Mógłbym to zrobić w TListBox, ale w nim jak jest zaznaczony item system rysuje wiejską ramkę taką, jak w MS Paint podczas zaznaczania regionu.

Niestety nie wiem, czy w TListView da się ustawiać itemy w kilku kolumnach (w TListBox chyba jest właściwość Columns). O taką rzecz mi chodzi.

Jeżeli mam na formie TListView, ustawię mu ViewStyle na vsIcon i dodam kilka itemów, dorzucam na formę TImageList i w nim ustawiam rozmiar przechowywanej grafiki na 100x100 pikseli, po czym w TListView ustawiam właściwość LargeImages na ww. TImageList. Teraz rozmiar grafiki w każdym TListView ma rozmiar 100x100 pikseli, ale rozmiar itemu jest większy. Pod grafiką o rozmiarach 100x100 pikseli jest jeszcze rysowany tekst itemu (to jest dokładnie to samo, gdy w dowolnym folderze mamy pliki i ustawimy widok na kafelki - jest grafika (czyli ikona) i tekst poniżej (czyli nazwa pliku)). Ja chcę się pozbyć tej nazwy, chcę tylko obszar grafiki dokładnie tak, jak jest to w TListBox.

Niestety nie potrafię tego opisać tak, żebyście zrozumieli dokładnie o co mi chodzi...

Najprościej mówiąc, chcę zaprogramować TListView tak, by wyglądał jak TListBox z pięcioma kolumnami.

EDIT: Dorzucam przykład w załączniku. Chcę, aby TListView wyglądał tak jak TListBox w tym przykładzie (tyle że w nim jest trzy kolumny dla przykładu, ja potrzebuję pięć).

0

Wiem cimak :)

Ale bardzo mi zależy, żeby to zrobić w TListView.

EDIT: Ewentualnie napiszcie, w jaki sposób rozróżnić, czy w miejscu kliknięcia jest jakiś item czy nie (Tak jak ma to miejsce w TListView - jeżeli jest item - zaznacza go, jeżeli nie ma itemu - odznacza wszystkie).

0

Nie pamiętam czy i jak da się ustawić TListView aby można było podświetlić tylko element w danej kolumnie, a nie tylko pierwszą kolumnę lub cały wiersz (przy własności RowSelect ustawionej na True), ale najpewniej w OnClick wystarczy poniższy kod, o ile to o takie coś Tobie chodzi.

var
  LI : TListitem;
begin
  LI := ListView1.Items[ListView1.ItemIndex];
  if LI <> nil then
  begin
    ShowMessage('Wybrano element.');
  end
  else
  begin
    ShowMessage('Nie wybrano żadnego elementu!');
  end;
end;
0
BoZzDoG napisał(a)

Koniecznie ma to być komponent TListView. Mógłbym to zrobić w TListBox, ale w nim jak jest zaznaczony item system rysuje wiejską ramkę taką, jak w MS Paint podczas zaznaczania regionu.

Chodzi o to? http://4programmers.net/Forum/Delphi_Pascal/155506-Listbox_canvas_mrówki

Edit: Nie zauważyłem dopiski cimak'a.

0

olesio, w TListView wiem jak się to robi, ale w TListBox nie...

Skupmy się teraz na TListBox. Chcę go tak przerobić, żeby przypominał wyglądem TListView, czyli usunąć systemową ramkę itemu gdy jest zaznaczony (to już mam) i rozróżnić, czy kliknięto w puste miejsce komponentu (tam gdzie nie ma żadnego itemu) czy w jakiś item.

Jeżeli chodzi o TListView, tam jest zaprogramowane, jak kliknie się w jakikolwiek item, czy jest zaznaczony czy nie, automatycznie go zaznacza, a resztę odznacza. A jeżeli klinie się w puste miejsce komponentu (tam gdzie żadnego wiersza nie ma), zostają odznaczone wszystkie, także automatyczne. To samo chciałbym uczynić z TListBox, bo on obsługuje itemy w dowolnej liczbie kolumn.

Jeżeli dalej nie rozumiecie, postaram się jeszcze jaśniej wytłumaczyć o co mi chodzi.

EDIT: olesio, jeżeli miałbym w TListView podświetlać wybraną kolumnę, musiałbym w OnMouseDown i w OnMouseUp sprawdzać w którym miejscu itemu dokładnie kliknięto. Zdarzenie OnDrawItem prawdopodobnie zostało by automatycznie wygenerowane (jak to zwykłe kliknięcie), ale musiałbym je jakoś powiązać z OnMouseDown, żeby gdzieś przechował numer kolumny którą kliknięto. W samym zdarzeniu mam w parametrze podany Item, z niego wyciągnę ItemIndex, ale numer kolumny ww muszę gdzieś mieć przechowany, żeby wiedzieć podczas rysowania wiersza, gdzie namalować ramkę zaznaczenia (którą kolumnę). Muszę przetestować kilka pomysłów. Dam znać co mi z tego wyszło. A tymczasem proszę, zastanówcie się nad tym:

Ja napisał(a)

Skupmy się teraz na TListBox. Chcę go tak przerobić, żeby przypominał wyglądem TListView, czyli usunąć systemową ramkę itemu gdy jest zaznaczony (to już mam) i rozróżnić, czy kliknięto w puste miejsce komponentu (tam gdzie nie ma żadnego itemu) czy w jakiś item.

0
BoZzDoG napisał(a)

[...] rozróżnić, czy kliknięto w puste miejsce komponentu (tam gdzie nie ma żadnego itemu) czy w jakiś item.

listbox powinien miec cos takiego jak ItemAtPos(x,y).

0

Już wszystko wiem. Poeksperymentowałem trochę i mam rozwiązanie.

W załączniku przykładowy program. Dziękuję za zainteresowanie. Pozdrawiam.

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