CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - ListView i progressbar + image w Details View

ListView i progressbar + image w Details View

dział ogólny

ListView i progressbar + image w Details View

Nowy postprzez Slynx » niedziela, 9 stycznia 2011, 16:58

Dopiero przygotowuje projekt i sprawdzam czy da się zrobić pewne elementy, a raczej nie czy da, a jaką to będzie miało wydajność.
ListView idealnie nadaje się pod względem struktury, ale są problemy z dodaniem obiektów, np. progressbar czy obrazek w jednej z komórek wiersza.

Zrobiłem to, jeśli chodzi o progressBar, ale kod mi się nie podoba. Gdy dorzucę jeszcze obrazek, który trzeba "powiesić" na pictureBox to wszystko może się posypać przy kilkudziesięciu rekordach. Za dużo obiektów, zbyt skomplikowane działanie, przynajmniej takie mam wrażenie.
Tu jest kod z dorzucenia progressbara i podpięcia go pod konkretny wiersz i kolumnę (dokładniej komórkę), działa włącznie z resize kolumny.

KOD cpp:     UKRYJ  
//obiekt progressBar jako global (poza eventami)
                        static ProgressBar ^ pg = gcnew ProgressBar();
//tu mamy aktywację progressbarów w pełnym działaniu (to oczywiście prototyp, składanie na szybko by sprawdzić tylko jak i czy działa)
private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {

                         this->listView1->Controls->Add(pg);
                         pg->Style = System::Windows::Forms::ProgressBarStyle::Continuous;

                         System::Drawing::Rectangle ^ aa = System::Drawing::Rectangle(listView1->Items[1]->GetBounds(System::Windows::Forms::ItemBoundsPortion::Label));
                         System::Drawing::Size ^ aaa = System::Drawing::Size(listView1->Items[1]->SubItems[1]->Bounds.X, listView1->Items[1]->SubItems[1]->Bounds.Y);

                         pg->Size = System::Drawing::Size(listView1->Items[1]->SubItems[1]->Bounds.Width, aa->Height);
                         pg->Location = System::Drawing::Point(aaa);

                         pg->Refresh();

                 }
//podobne jest w zdarzeniu "listView1_ColumnWidthChanging" więc nie będę wklejał

 


Całość widać na screenie :
Obrazek

Podobnie tyczy się obrazka, tzn. tak miałem zamiar zrobić, ale jak mówiłem całość mi się niespecjalnie podoba.

Ma ktoś może jakieś lepsze rozwiązanie ? :/

Liczba elementów nie powinna przekroczyć 100-120, więc pod to trzeba dopasowywać wydajność.
Gdzieś szukałem w google, to ktoś zrobił na 37k elementów to mu się ładowało 2-3 min, dlatego tak informuję ; p

---
Jeszcze mam takie inne pytanie, nie dotyczące listView. Zauważyłem pewien fajny efekt w programie, wiem że był pisany w Visualu, ale za cholerę nie mogę znaleźć tego komponentu, a na 99 % należy on do standardowych (jak, np. listview). To jest coś w stylu takich rozwijanych menu, jeden pod drugim, z tym że jak rozwiniesz to komponenty niższe się przesuwają w dół (tutaj na 100 % flowLayoutPanel). Klikasz na nagłówke i rozwija się lista, coś jak comboBox, tylko, że jego opcje są nakładane na inne komponenty. Nie wiem czy wystarczająco jasno opisuje ;p Bardzo elegancko to wygląda, więc chciałem to wrzucić u siebie. Można by dodać coś w stylu buttonów kolejno jeden pod drugim, a kliknięcie na główny (reprezentujący nagłówek) wywołuje Hide() u innych należących do tej grupy, jednak to nie to samo. Może ktoś wie co to za komponent i jak skonfigurowany ? Ktoś stosował to u siebie...
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Firefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Slynx » niedziela, 9 stycznia 2011, 20:14

Jeśli chodzi o ten komponent o którym wspominałem na dole to już nieistotne, stworzyłem go ;p (panel+buttony+timer) ;) Czekam na pomoc z resztą.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Firefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Cyfrowy Baron » niedziela, 9 stycznia 2011, 21:47

Przeglądałem ten Twój kod i jedyne co mogę stwierdzić, to iż w 90% jest dla mnie niezrozumiały. Całe to C++/CLI za bardzo różni się od C++ bym mógł coś doradzić, może poza jednym, że cokolwiek wstawiasz do ListView powinieneś to robić w zdarzeniu OnCustomDraw, OnCustomDrawItem, OnCustomDrawSubItem, lub OnDrawItem, wtedy obiekt sam zarządza tym co wstawiasz, przez co kod wykonuje się dużo szybciej. Tak kiedyś wstawiałem Progressbar do ListViewm, ale jeden, tylko zamieniał się wierszami.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Slynx » środa, 12 stycznia 2011, 00:54

Z tymi zdarzeniami to jest dobry pomysł, spróbuję to dodać. Mam natomiast trochę inne pytanie.
To co nas interesuje wygląda następująco

KOD cpp:     UKRYJ  
                                         System::IO::StreamWriter ^ sw = gcnew System::IO::StreamWriter(path + file_name->Insert(file_name->Length-4, temp + file_number.ToString()));
                                         while (!sr->EndOfStream)
                                         {
                                                 sr->ReadBlock(buffer, 0, buffer->Length);
                                                 sw->Write(buffer);
                                                 temp_bytes_per_segment += buffer->Length;

                                                 if ((temp_bytes_per_segment + buffer->Length) >= (Size_in_Kbytes * 1024))
                                                 {
                                                         sr->ReadBlock(buffer, 0, (Size_in_Kbytes * 1024) - temp_bytes_per_segment);
                                                         sw->Write(buffer, 0, (Size_in_Kbytes * 1024) - temp_bytes_per_segment);
                                                         temp_bytes_per_segment = 0;
                                                         sw->Close();
                                                 }

                                                 if (temp_bytes_per_segment == 0)
                                                 {
                                                         file_number += 1;
                                                         if (file_number.ToString()->Length == 1) temp = "00";

                                                         if (file_number.ToString()->Length == 2) temp = "0";

                                                         if (file_number.ToString()->Length == 3) temp = "";
// tworzenie obiektu sw
                                                        System::IO::StreamWriter ^ sw = gcnew System::IO::StreamWriter(path + file_name->Insert(file_name->Length-4, temp + file_number.ToString()));
//---------------
                                                 }
                                         }
 


interesuje nas jedna linijka, ale wklejam całość by była jasna struktura. Jak zaznaczyłem wewnątrz instrukcji if jest tworzony obiekt sw typu StreamWriter, problemem jest, to, że jest widoczny jedynie wewnątrz, a potrzebuje go dla całej pętli while. Czuję, że to coś z początku podręcznika programowania, ale jakoś nie mogę nic z tym zrobić ;p

Kompilator konkretnie wskazuje na "sw->Write(buffer);", że nie można zapisać danych do zamkniętego obiektu co chyba jest oczywiste. Więc jak tworzone obiekty wyrzuca się na zewnątrz bieżącego bloku ?
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Firefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Cyfrowy Baron » środa, 12 stycznia 2011, 10:39

StreamWriter, problemem jest, to, że jest widoczny jedynie wewnątrz, a potrzebuje go dla całej pętli while.


Jeżeli tworzysz jakiś obiekt wewnątrz jakiegokolwiek bloku, czy to while, if, for, itp. to taki obiekt poza tym blokiem nie jest widoczny. Musisz utworzyć deklarację tego obiektu poza pętlą if, ale wewnątrz while, lub nawet poza while, zależy do czego jest tobie potrzebny i jak będzie używany. Nie powiem konkretnie jak to masz tutaj zrobić, gdyż ten sposób tworzenia obiektów jest mi obcy, ale w C++ np. dla klasy TMemoryStream mogło by to wyglądać tak:

KOD cpp:     UKRYJ  
 while(warunek)
{
  if( warunek)
  {
    TMemoryStream *memStr = new TMemoryStream();
   
    // jakieś operacje na obiekcie memStr

   delete memStrem // koniecznie trzeba usunąć, inaczej pojawi się wyciek pamięci.
  }
}


W powyższym przykładzie obiekt memStr istnieje tylko dla warunku if, nie ma go poza warunkiem, jeżeli chcę mieć dostęp do tego obiektu w całej pętli while:

KOD cpp:     UKRYJ  
 while(warunek)
{
  TMemoryStream *memStr = new TMemoryStream();

  if( warunek)
  {  
    // jakieś operacje na obiekcie memStr
  }

   delete memStrem // koniecznie trzeba usunąć, inaczej pojawi się wyciek pamięci
}


W tym przykładzie obiekt memStr jest dostępny zarówno dla while jak i dla if, ale nie jest dostępny poza while.
W kolejnym przykładzie obiekt memStr jest dostępny dla całej funkcji jak czyli dla wszystkiego co znajduje się w tej funkcji while, ale nie jest dostępny poza funkcją.

KOD cpp:     UKRYJ  
void __fastcall Funkcja(void)
{
 TMemoryStream *memStr = new TMemoryStream();

 while(warunek)
 {
  if( warunek)
  {  
    // jakieś operacje na obiekcie memStr
  }
 }

 delete memStrem // koniecznie trzeba usunąć, inaczej pojawi się wyciek pamięci
}


We wszystkich trzech przykładach mamy do czynienia z obiektem lokalnym.
Trochę mnie dziwi, że nie rozróżniasz obiektów, metod, zmiennych itp. na lokalne, globalne, prywatne i publiczne. Nie wiem czy w C++/CLI prywatne i publiczne istnieją, ale lokalne i globalne na pewno.
W swoim kodzie tworzysz obiekt dwukrotnie poza pętlą while i w warunku if, ale to w żadnym przypadku nie jest ten sam obiekt, to dwa różne obiekty i odpowiada to takiej sytuacji w C++:

kod niepoprawny - nie naśladować.
KOD cpp:     UKRYJ  
 TMemoryStream *memStr = new TMemoryStream();
 while(warunek)
 {
   if(warunek)
   {
     TMemoryStream *memStr = new TMemoryStream();

     delete memStr;
   }

 };
 delete memStr;


Kod jest niepoprawny, pojawia się wyciek pamięci, gdyż obiekt utworzony poza pętlą while zostaje zastąpiony tym utworzonym w warunku if.

Skoro utworzyłeś obiekt sw poza pętlą while to w warunku if nie powinieneś go już tworzyć, lecz używać. Pojawia się tutaj oczywiście problem, bo jak przypuszczam - nie znam tej klasy - nie możesz otworzyć nowego pliku nie tworząc obiektu. Musisz więc zmienić koncepcję tego kodu.



Kompilator konkretnie wskazuje na "sw->Write(buffer);",


Cały mój wykład na niewiele się zda bo akurat obiekt w tym warunku powinien być dostępny, ale jak już gdzieś, kiedyś pisałem w C++/CLI zarządzenia obiektami odbywa się inaczej niż w C++, więc nie wiem co z tym fantem zrobić... :roll:
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ListView i progressbar + image w Details View

Nowy postprzez polymorphism » środa, 12 stycznia 2011, 11:18

Kod jest niepoprawny, pojawia się wyciek pamięci, gdyż obiekt utworzony poza pętlą while zostaje zastąpiony tym utworzonym w warunku if.

Nieprawda! Wskaźnik memStr, zdefiniowany wewnątrz if'a, przysłania ten zdefiniowany w bloku nadrzędnym, w tym przypadku przed pętlą while. Ten zapis jest poprawny.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Cyfrowy Baron » środa, 12 stycznia 2011, 11:25

Cofam co napisałem. Inny kod pisałem na forum i trochę inaczej w kompilatorze:

KOD cpp:     UKRYJ  
 int x = 0;

 TMemoryStream *memStr = new TMemoryStream();
 while(1)
 {
   if(x == 0)
   {
     TMemoryStream *memStr = new TMemoryStream();

     memStr->LoadFromFile("c:\\temp");

     delete memStr;
   }
 };
 delete memStr;


Uznałem to za błąd, gdyż program się zawieszał, a wszystko z winy pętli while. Od początku wydawało mi się, że to powinny być dwa obiekty i powinno działać, ale uznałem, że skoro program się zawiesza to muszę się mylić. Nie przemyślałem tego do końca, tym bardziej, że w swoich programach zdarza mi się stosować tego typu konstrukcje, tyle że nie mam w zwyczaju używania tych samych nazw.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: ListView i progressbar + image w Details View

Nowy postprzez Slynx » środa, 12 stycznia 2011, 19:55

Ok, świetnie zaraz to sprawdzę. I tak jak powiedziałeś, nie mogę pracować na tym samym obiekcie, bo przy tworzeniu podaje mu "unikalny" argument, którego potem zmienić nie można (choć pewnie sformułowałbyś to profesjonalniej;p). Ale jako, że ten temat był wstrzymany ze względu na problem to zająłem się inną częścią programu, więc zapraszam do nowego tematu ;p
I nie staraj się mi przedstawiać konkretnego kodu, bo widzę, że zasłaniasz się strasznie nieznajomością struktury C++/CLI tylko pisz to tak jakby wyglądało to u Ciebie. Nie mam problemów z przekładaniem kodu z innych języków na C++/CLI.

A poly ma naturalnie rację. O przysłanianiu obiektu dużo było w Sumfonii.

[EDIT]
He, he. Nie ma tematu. Mogę powiedzieć, że to forum jest magiczne. Ponad 4 godziny siedziałem i szukałem jak przeprowadzić poprawne uwierzytelnianie dla serwera SMTP. I nic. Już miałem właśnie temat zakładać. Piszę Temat, wstawiłem kod... czytam, czytam, czytam.... Oświeciło mnie ! xD Już zrobiłem
A o co chodziło ?
Cały czas ustawiałem uwierzytelnianie dla innych serwerów. Przy opisie było "[...] credential cache for use with protocols other than SMTP [...]", a ja to słówko "other" jakoś przeoczyłem i kombinowałem na wszystkie możliwe sposoby ustawiając uwierzytelniania dla zupełnie innych serwerów ;p Do tego tematu jeszcze wrócę, tylko skończę to co teraz zacząłem.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 21 gości

cron