Na forum 4programmers.net korzystamy z plików cookies. Część z nich jest niezbędna do funkcjonowania
naszego forum, natomiast wykorzystanie pozostałych zależy od Twojej dobrowolnej zgody, którą możesz
wyrazić poniżej. Klikając „Zaakceptuj Wszystkie” zgadzasz się na wykorzystywanie przez nas plików cookies
analitycznych oraz reklamowych, jeżeli nie chcesz udzielić nam swojej zgody kliknij „Tylko niezbędne”.
Możesz także wyrazić swoją zgodę odrębnie dla plików cookies analitycznych lub reklamowych. W tym celu
ustaw odpowiednio pola wyboru i kliknij „Zaakceptuj Zaznaczone”. Więcej informacji o technologii cookie
znajduje się w naszej polityce prywatności.
Aplikacja pobiera z tabeli około 1200 wpisów, to jest w zasadzie błyskawiczne, muszę to jednak wstawić do ListView i pogrupować. W sumie wszystkie rekordy (1200) będą w około 100 grupach. W prostej pętli For dopisuję kolejne rekordy i w razie czego uzupełniam grupy.
O ile samo dodanie rekordu nie jest problemem ListView.Items.Add(); podobnie jak uzupełnienie reszty danych to już dodanie grupy ListView.Groups.Add(); trwa wyraźnie za dłużej.
Zauważyłem, że czas ten rośnie im więcej jest grup. Przy około 30 grupach podanie kolejnej zajmuje około sekudnę. Można na to jakoś wpłynąć, przyspieszyć? Załadowanie do ListView 1200 rekordów trwa około minuty.
Pokombinowałem nieco i okazuje się, że wszystko działa szybciej jeżeli wpierw dodaję grupy, a później pozycje. Jeżeli grupy uzupełniam w trakcie dodawania pozycji to ListView strasznie spowalnia.
W tej chwili pomimo tego, że mam 2 pętle, pierwsza która tworzy grupy i druga która dopisuje pozycje do ListView, to działa to w zasadzie bez jakiegokolwiek opóźnienia...
Mam inne pytanie, tym razem związanie z wielkością czcionki użytej dla grup. Da się ją jakoś zmienić? Font obiektu ListView odnosi się tylko do pozycji. Grupy korzystają z czegoś innego. czego?
@amidar: każda kontrolka posiadająca możliwość przechowywania mnóstwa itemów obsługuje metody BeginUpdate i EndUpdate. Służą one właśnie po to, aby poinformować kontrolkę o tym, że zawartość będzie zmieniania. Dzięki temu po każdorazowej zmianie zawartości (edycji, wstawieniu czy usunięciu pozycji), kontrolka nie odświeża swojej zawartości, a więc nie marnuje czasu na absolutnie zbędne operacje (np. przemalowanie interfejsu). Dlatego też zawsze używaj tych metod, jeśli tylko są dostępne. A dostępne są przede wszystkim w ListView, ListBox, ComboBox itd.
Czyli aby mocno przyspieszyć uzupełnianie kontrolki w dane, na samym początku wywołaj ListView.BeginUpdate, następnie zrób co masz zrobić (dodaj dane) i na samym końcu zawołaj ListView.EndUpdate.
Ale kosmicznej optymalizacji nie ma się co spodziewać po użyciu tych metod. Równie dobrze wąskie gardło może być gdzieś indziej (czyli w samym kodzie pobierającym dane lub je grupującym).
Mam inne pytanie, tym razem związanie z wielkością czcionki użytej dla grup. Da się ją jakoś zmienić? Font obiektu ListView odnosi się tylko do pozycji. Grupy korzystają z czegoś innego. czego?
VCL domyślnie korzysta ze stylu systemowego, tak więc aby móc malować pozycje inaczej, można skorzystać ze zdarzeń pozwalających własnoręcznie je malować. Jest ich kilka, więc jest w czym wybierać.
@amidar: jeśli chcesz wiedzieć coś więcej to pokaż kod przygotowujący zawartość kontrolki – być może on też wcale nie jest jakiś specjalnie optymalny i to powoduje problem wydajnościowy.
Nie sugeruj się nazwą, ponieważ to jest wielokolumnowy TreeView, a więc może działać jak ListView.
Tylko lepiej, szybciej (pewnie 100x szybciej ; eee... to nieprawda, ponieważ "Virtual Treeview is extremely fast. Adding one million nodes takes only 700 milliseconds!*") i o naprawdę niebagatelnych możliwościach.
Tu więcej i łobrazki: https://www.jam-software.com/virtual-treeview/features.shtml
Wielkie dzięki za wszelkie uwagi. BeginUpdate i EndUpdate dołożyłem, ale po zmianie kolejności dodawania elementów różnica nie jest już jakaś specjalnie wielka. Całe przeładowanie trwa poniżej sekundy... jest to akceptowalne w porównaniu do poprzednich 60 sekund ;)
Za to zainteresował mnie Virtual TreeView. Wygląda obiecująco, być może podmienię go jeszcze teraz zanim zabrnę za daleko ;)
Wielkie dzięki za wszelkie uwagi. BeginUpdate i EndUpdate dołożyłem, ale po zmianie kolejności dodawania elementów różnica nie jest już jakaś specjalnie wielka. Całe przeładowanie trwa poniżej sekundy... jest to akceptowalne w porównaniu do poprzednich 60 sekund ;)
Ha! Wiedziałem. :D
To też nie jest tak, że standardowe komponenty są jakoś szczególnie powolne (szczególnie szybkie też nie) – po prostu trzeba się nauczyć je obsługiwać. No i pozostaje jeszcze wydajność kodu pozyskującego dane, które dodajesz do kontrolki. W nim też może i można coś przyspieszyć, jednak bez kodu niczego więcej nie mogę napisać.
Żeby móc jeszcze bardziej zoptymalizować ten kod, trzeba by kuknąć do kodu tego komponentu i sprawdzić co wykonuje w danych przypadkach. W ten sposób można dojść do efektywnego (acz mniej czytelnego) rozwiązania. Choć pewnie nie ugra się tym zbyt wiele.
Za to zainteresował mnie Virtual TreeView. Wygląda obiecująco, być może podmienię go jeszcze teraz zanim zabrnę za daleko ;)
Na pewno warto poznać tę kontrolkę, bo daje niesamowite możliwości. Przykłady użytkowania możesz znaleźć w wyszukiwarce (przykładowe kody również). Standardowe kontrolki przydają się do prostych zastosowań, jednak do bardziej zaawansowanych i fikuśnych trzeba się gimnastykować i tu z pomocą przychodzi VirtualTreeView.