Extinderea controlului arborelui

Codul sursă pentru WinFormControls.exe poate fi descărcat din Centrul de cod MSDN.

  • Dezvoltarea de comenzi personalizate ale Windows utilizând Visual Basic .NET (Prezentare generală)
  • Adăugarea validării expresiei regulate
  • Combinarea mai multor controale într-una
  • Extinderea controlului TreeView
  • Desenarea propriilor controale cu GDI +
  • introducere
  • Proiectarea unei structuri legate de arbori
  • Implementarea datelor legale ® Windows ® Forms a fost investită extraordinar în codificare și testare și toate aceste lucruri trebuie să fie făcute din nou dacă controlul trebuie început complet de la zero. Având în vedere acest lucru, acest exemplu va moșteni de la controlul Formular Windows existent - Tree View - și îl va configura. Codul pentru acest nou control TreeView poate fi descărcat într-un singur fișier împreună cu alte exemple de design de control și o aplicație de probă care demonstrează modul în care acest avansat TreeView poate fi utilizat împreună cu alte controale legate de date.

Proiectarea vizualizării de arbori legate de date

Sub rezerva adăugării de legare de control TreeView atins periodic dezvoltatorii Windows, dar elementul de control de bază încă nu acceptă din cauza diferențelor esențiale dintre TreeView și alte controale, cum ar fi ListBox sau Datagrid date: TreeView afișează o serie de date ierarhice. tabel separat de date este destul de ușor să se afișeze în listbox sau DataGrid, dar pentru a profita de natura ierarhică a TREEVIEW pentru a afișa aceleași date nu este atât de simplu. Există mai multe moduri diferite de a folosi TreeView pentru a afișa date, dar o metodă este cea mai frecventă: gruparea datelor în anumite domenii ale tabelului prezentat în Fig. 1.







Fig. 1. Afișarea datelor în TreeView

Pentru acest exemplu, intenționați să creați un control TreeView în care să puteți transfera un set de date plat (a se vedea figura 2) și să atingeți cu ușurință rezultatul prezentat în Fig. 1.

Fig. 2. Un set de rezultate plate care conține toate informațiile necesare pentru a crea arborele prezentat în Fig. 1.

Când construiți un control personalizat înainte de a începe codarea, vă recomandăm să înțelegeți în mod clar în ce scop acest control va fi utilizat de un alt dezvoltator. În acest caz, dezvoltatorul (datele și rezultatul dorit sunt descrise mai sus) pot efectua gruparea descrisă cu ajutorul mai multor rânduri din următorul cod:

Notă. Acest cod nu este exact ceea ce era necesar, dar nu este prea departe de rezultatul dorit. La dezvoltarea controlului a devenit evident că este necesar să asociați indexul de imagine din ImageList asociat controlului TreeView cu fiecare nivel de grupare. Prin urmare, a fost adăugat un parametru suplimentar pentru metoda AddGroup.

Note la imagine:
Noduri de grup - noduri de grup
Noduri de frunze - noduri finale

Fig. 3. Noduri de grup și noduri finale

Diferența dintre nodul țintă și grupul de noduri (vezi. Fig. 3) este foarte importantă pentru articol, deoarece sa decis să proceseze cele două tipuri de noduri în diferite moduri prin crearea de clase personalizate pentru fiecare tip și generarea de diverse evenimente în funcție de tipul de nod.

Implementarea legării datelor

Primul pas în scrierea codului pentru acest control este de a crea un proiect și o clasă de start corespunzătoare. În acest caz, creați mai întâi un nou proiect de Windows Control Library și apoi, ștergând clasa UserControl în mod implicit, înlocuiți-o cu o nouă clasă care moștenește din controlul TreeView:

Din acest punct de lucru, munca se face cu un control pe care îl puteți pune în formă și îl face să arate și să funcționeze la fel ca un TreeView normal. Următorul pas este să adăugați codul care gestionează noua funcționalitate în această versiune a TreeView - conectând și grupând datele.

Adăugarea unei proprietăți a unei surse de date

Toate funcționalitățile noului control sunt importante, dar cele două caracteristici cheie ale construirii unui control complex legat de date sunt procesarea proprietății DataSource și obținerea proprietăților unui element individual de la fiecare obiect din sursa de date.

Crearea unei proceduri de proprietate

Pentru a începe, este necesar ca orice control care implementează legarea complexă a datelor să implementeze procedura DataSource și să suporte variabilele membre corespondente:

Interfața IList

Obiectele care pot fi utilizate ca sursă de date pentru legarea complexă a datelor suportă în general o interfață IList care oferă datele ca o colecție de obiecte, precum și câteva proprietăți utile, de exemplu Count. Noul control TreeView necesită un obiect pe care IList îl susține să-l asocieze, dar cealaltă interfață IListSource este, de asemenea, perfect potrivită, deoarece oferă o metodă simplă (GetList) pentru a obține obiectul IList. Când este setată proprietatea DataSource, este recomandat să stabiliți mai întâi dacă un obiect valid a fost acordat, adică care sprijină IList sau IListSource. Se recomandă să selectați IList, deoarece dacă obiectul furnizat acceptă numai IListSource (de exemplu, DataTable), atunci metoda GetList () a acestei interfețe este folosită pentru a obține un obiect valid.

Unele obiecte care implementează IListSource (de exemplu, DataSet) conțin de fapt mai multe liste, ceea ce este indicat de proprietatea ContainsListCollection. Dacă această proprietate este True, GetList returnează un obiect IList care reprezintă o listă de subliste multiple. În acest exemplu, sa hotărât menținerea legăturilor direct cu obiectele IList sau IListSource care stochează doar un obiect IList și ignoră obiecte precum DataSet, pentru care este necesară determinarea suplimentară a sursei de date.

Notă. Dacă aveți nevoie de suport pentru acest tip de obiect (DataSet sau similar), puteți adăuga oa doua proprietate (de exemplu, DataMember) care specifică sub-lista specifică utilizată pentru legare.

Dacă este furnizată o sursă de date validă, va fi creată o instanță a clasei CurrencyManager (cm = Me.BindingContext (Value)) în rezultatul final. Această instanță este stocată într-o variabilă locală, deoarece va fi utilizată pentru a accesa sursa de date, proprietățile obiectului și informațiile despre poziție.







Adăugați proprietăți afișate și valori

Prezența sursei de date este primul pas în legarea datelor complexe, dar controlul trebuie să știe care câmpuri particulare sau proprietățile de date ar trebui folosite pentru valoare și afișare. Membrul de afișare va fi folosit ca antetul nodului de copaci, membrul Valoare va fi accesibil prin proprietatea Value a nodului. Aceste proprietăți sunt doar șiruri de caractere care reprezintă numele câmpurilor sau proprietățile și sunt ușor de adăugat la control:

În acest TreeView, aceste proprietăți reprezintă elemente de afișare și valori numai pentru nodurile finale, informațiile corespunzătoare pentru fiecare nivel de grupare sunt definite în metoda AddGroup.

Utilizând obiectul CurrencyManager

În proprietatea DataSource discutată anterior, o instanță a clasei CurrencyManager a fost creată și stocată într-o variabilă de nivel de clasă. Clasa CurrencyManager accesată prin acest obiect este cheia implementării legării datelor, deoarece are proprietăți, metode și evenimente care permit:

  • accesați obiectul IList de bază al sursei de date;
  • primiți și setați câmpuri sau proprietăți pe obiectul din sursa de date;
  • Sincronizați comanda cu alte controale legate de date în aceeași formă.

Obținerea valorii proprietății / câmpului

Obiectul CurrencyManager vă permite să preluați valorile proprietății sau câmpurile de elemente individuale din sursa de date, de exemplu valorile câmpului DisplayMember sau ValueMember, prin metoda GetItemProperties. Apoi, folosim obiectele PropertyDescriptor pentru a obține valoarea unui anumit câmp sau a unei proprietăți a unui anumit element de listă. Următorul fragment de cod arată modul în care sunt create aceste obiecte PropertyDescriptor și modul în care funcția GetValue poate fi utilizată mai târziu pentru a obține valoarea proprietății unui element din sursa de date de bază. Observați proprietatea Listei obiectului CurrencyManager: oferă acces la instanța IList cu care a fost asociat controlul:

GetValue returnează un obiect indiferent de tipul datelor de bază ale proprietății, deci înainte de utilizare valoarea de retur trebuie convertită.

Suport pentru sincronizarea controalelor legate de date

CurrencyManager are o altă caracteristică importantă: în plus față de furnizarea accesului la sursa de date conectată și la proprietățile elementului, aceasta coordonează legarea datelor dintre acest control și orice alte controale care utilizează aceeași sursa de date. Acest suport asigură că mai multe controale asociate cu o singură sursă de date rămân pe același element din sursa de date. Pentru controlul în cauză, trebuie să vă asigurați că atunci când selectați un element din arbore, orice alte controale asociate aceleiași surse de date indică același element (înregistrare, șir sau tuplu, utilizând terminologia bazei de date). Pentru a face acest lucru, trebuie să înlocuiți metoda OnAfterSelect a controlului de bază TreeView. În această metodă, numită după selectarea unui nod de copaci, setați proprietatea Poziție a obiectului CurrencyManager la indexul elementului selectat curent. O aplicație tipică furnizată odată cu controlul TreeView ilustrează modul în care fenomenul comenzilor sincronizate facilitează crearea interfețelor de utilizator legate de date. Pentru a facilita determinarea poziției elementului selectat în listă, utilizați clasele personalizate create TreeNode (TreeLeafNode sau TreeGroupNode) și salvați indexul listei fiecărui nod la proprietatea Position:

Proprietăți Reglarea poziției CurrencyManager obiect permite să păstreze sincronizarea cu alte elemente de control ale elementului curent selectat, dar, de asemenea, generează evenimente CurrencyManager atunci când alte controale de a schimba poziția, astfel încât a fost posibil să se modifice elementul selectat, după caz. Pentru a construi un mic bine conectat cu componenta de date, alegerea trebuie să fie deplasat prin schimbarea poziției sursei de date, iar în cazul în care datele articol a schimbat, afișajul trebuie să fie actualizat. CurrencyManager generează trei evenimente: CurrentChanged, ItemChanged și PositionChanged. Ultimul eveniment este direct; CurrencyManager unul dintre scopurile este de a controla indicatorul poziția curentă pentru sursa de date, astfel încât mai multe display-uri legate de control aceeași înregistrare sau lista de elemente, iar acest eveniment va fi generat pentru orice schimbare a acestei poziții. În unele cazuri, alte evenimente se suprapun, deci nu sunt foarte clare. Aici puteți vedea cum să le folosiți în controlul dvs. de utilizator: PositionChanged este un eveniment simplu, deci luați în considerare imediat; utilizați-l când trebuie să ajustați elementul selectat curent într-un control complex al datelor, cum ar fi acest arbore. Evenimentul ItemChanged este generat atunci când orice element din sursa de date este modificat și CurrentChanged este generat numai când elementul curent este schimbat.

În cadrul analizei TreeView, sa constatat că toate cele trei evenimente au fost generate atunci când a fost selectat un nou element, deci sa decis să se ocupe de evenimentul PositionChanged când elementul selectat curent a fost schimbat și alte două evenimente nu au fost procesate deloc. În documentația .Net Framework, se recomandă să convertiți sursa de date într-un IBindingList (dacă este compatibil cu IBindingList) și să utilizați în schimb evenimentul ListChanged, dar aceste funcționalități nu au fost implementate:

Conversia unei surse de date într-un copac

Când ați terminat cu datele de cod cu caracter obligatoriu, puteți începe să lucreze la adăugarea restului de cod pentru a manipula nivelurile de grupare, a construi un copac în mod corespunzător și se adaugă câteva evenimente personalizate, metode și proprietăți.

Gestionarea grupurilor

Trebuie să creați funcțiile AddGroup, RemoveGroup și ClearGroups pentru a configura colecția de grupuri. De fiecare dată când schimbați grupurile de colectare copac ar trebui să fie redesenată (pentru a reflecta noua configurație), astfel încât a fost creată procedura generală GroupingChanged, cauzată de un cod diferit peste tot în control, atunci când orice modificări și actualizări arborelui: P

Construirea unui copac

Actualizarea actuală a copacilor este gestionată de două proceduri: BuildTree și AddNodes. Codul lor este destul de lungă, astfel încât să încerce să facă o trecere în revistă a comportamentului lor și nu include toate codul în acest articol (desigur, îl puteți descărca). După cum sa menționat anterior, un dezvoltator interactioneaza cu acest control prin stabilirea numărului de grupe care sunt apoi utilizate în BuildTree, pentru a seta nodurile de copac. BuildTree șterge nodul de colectare a curentului ciclat prin sursa de date la procesele de primul nivel de grupare (a se vedea. Publisher în exemplele și desenele din acest articol de mai sus), adăugând un nod pentru fiecare diferite grupe de valori (un nod pentru fiecare pub_id valoare în acest exemplu ) și apoi solicită AddNodes să umple toate nodurile sub primul nivel al grupării. AddNodes se solicită recursiv să proceseze orice număr de nivele adăugate la nodurile grupului și, respectiv, nodurile finale. Două clase personalizate bazate pe TreeNode, folosit pentru a distinge între grupurile de noduri și noduri de capăt, și fiecare tip de nod de set de proprietăți relevante.

Personalizarea evenimentelor TreeView

Când selectați un nod, controlul TreeView generează două evenimente: BeforeSelect și AfterSelect. Cu toate acestea, pentru un control mai bun al elementului au diferite evenimente la grupul de noduri și noduri finale, așa că adăugați evenimente personalizate BeforeGroupSelect / AfterGroupSelect și BeforeLeafSelect / AfterLeafSelect cu clase personalizate de parametri de evenimente, care sunt generate, în plus față de evenimentele de bază:

Clasele de noduri personalizate (TreeLeafNode și TreeGroupNode) și clasele parametrilor de eveniment personalizat sunt disponibile în codul care trebuie încărcat.

Aplicare tipică

Pentru a înțelege pe deplin tot codul din acest exemplu de control, analizați funcționarea acestuia în aplicație. Aplicația de probă furnizate lucrează cu date Microsoft Access pubs.mdb și ilustrează modul în care elementul de control copac interacționează cu alte controale de date aferente pentru a crea aplicații Windows. Caracteristica principală a acestui exemplu este că trebuie să acorde o atenție specială includerii Arborele de sincronizare cu alte controale aferente și selectarea automată a nodului arborelui atunci când sursa de date care urmează să fie căutate.

Notă. Această aplicație tipică (numită "TheSample") poate fi descărcată pentru acest articol.

Fig. 4. Demonstrație pentru TreeView legat de date

Controlul de control al copacilor legat de date discutat în acest articol nu este soluția pentru fiecare proiect care necesită un control Tree pentru a afișa informații din baza de date, dar ilustrează o modalitate de personalizare a acestuia pentru scopuri specifice. Nu uitați că majoritatea codului din acest control se potrivește cu codul în orice control complex al datelor pe care doriți să-l construiți și că puteți extinde această lucrare existentă pentru a simplifica dezvoltarea de controale în viitor.

În exemplul următor, „Desen de control proprii, folosind GDI +“ va fi ilustrată într-un mod mult mai simplu de punere în aplicare a datelor cu caracter obligatoriu în acele situații în care nu este nevoie de a utiliza o clasă de bază specifică (drept control) pentru moștenirea controlului TreeView.

Forumul programatorului
știri
comentarii
Programator magazin
Catalog de legături
căutare
Adăugați fișier
feedback-ul







Trimiteți-le prietenilor: