VB.NET: Ce s-a întâmplat cu Array-uri de control

click fraud protection

Omiterea matricelor de control de la VB.NET este o provocare pentru cei care predau despre tablouri.

  • Nu mai este posibil să copiați pur și simplu un control, cum ar fi o cutie de text, și apoi să-l lipiți (o dată sau de mai multe ori) pentru a crea un tablou de control.
  • Codul VB.NET pentru crearea unei structuri similare cu un tablou de control a fost, în toate cărțile de pe VB.NET pe care le-am cumpărat și online, mult mai mult și mult mai complex. Îi lipsește simplitatea codificării unui tablou de control care se găsește în VB6.

Dacă faceți referire la biblioteca de compatibilitate VB6, există obiecte acolo care acționează cam ca tablourile de control. Pentru a vedea ce vreau să spun, pur și simplu folosiți expertul de upgrade VB.NET cu un program care conține un tablou de control. Codul este din nou urât, dar funcționează. Vestea proastă este că Microsoft nu va garanta că componentele de compatibilitate vor fi acceptate în continuare și nu trebuie să le utilizați.

Codul VB.NET pentru a crea și utiliza „tablele de control” este mult mai lung și mult mai complex.

instagram viewer

Conform Microsoft, pentru a face ceva chiar mai aproape de ceea ce poți face în VB 6 necesită crearea unei „componente simple care să dubleze funcționalitatea tabloului de control”.

Pentru a ilustra acest lucru, aveți nevoie atât de o clasă nouă, cât și de un formular de găzduire. Clasa creează și distruge noi etichete. Codul complet al clasei este următorul:

Clasa publică LabelArray
Sistem de moștenire. Colecții. CollectionBase
Private ReadOnly HostForm As _
Sistem. Windows. Formulare. Formă
Funcție publică AddNewLabel () _
Ca sistem. Windows. Formulare. Eticheta
'Creați o nouă instanță a clasei Label.
Dim aLabel ca sistem nou. Windows. Formulare. Eticheta
'Adăugați eticheta în colecția
'listă internă.
Pe mine. Listă. Adăugați (aLabel)
'Adăugați eticheta în colecția Controale
'din formularul la care face referire câmpul HostForm.
HostForm. Controale. Adăugați (aLabel)
'Setați proprietăți initiale pentru obiectul Label.
o eticheta. Top = număr * 25
o eticheta. Lățime = 50
o eticheta. Stânga = 140
o eticheta. Tag = Eu. Numara
o eticheta. Text = „Etichetă” & Eu. Numara. ToString
Returnați aLabel
Funcția End
Sub public nou (_
Sistemul de gazdă ByVal ca sistem. Windows. Formulare. Formă)
HostForm = gazdă
Pe mine. AddNewLabel ()
Sub final
Default Public ReadOnly Property _
Articol (indexul ByVal ca număr întreg) ca _
Sistem. Windows. Formulare. Eticheta
obține
Returnare CType (Lista Me. Articol (index), _
Sistem. Windows. Formulare. Eticheta)
Încheiați
Proprietate finală
Subînlăturare publică ()
„Verificați pentru a vă asigura că există o etichetă de eliminat.
Daca eu. Numără> 0 Apoi
'Eliminați ultima Etichetă adăugată în tablou
'din colecția de controale de formular gazdă.
'Notă utilizarea proprietății implicite din
'accesarea tabloului.
HostForm. Controale. Eliminați (Me (Count. Me - 1))
Pe mine. Listă. RemoveAt (Numărul meu - 1)
End If
Sub final
Clasa finală

Pentru a ilustra modul în care ar fi utilizat acest cod de clasă, puteți crea un Formular care îl apelează. Va trebui să folosiți codul prezentat mai jos în formularul:

Clasa publică Form1. Sistem de moștenire. Windows. Formulare. Formă. #Region „Codul generat de Windows Form Designer” 'De asemenea, trebuie să adăugați afirmația:' MyControlArray = New LabelArray (Me) 'după apelul InitializeComponent () din. 'cod de regiune ascuns. 'Declarați un nou obiect ButtonArray. Dim MyControlArray As LabelArray. Sub Privat btnLabelAdd_Click (_. ByVal expeditor ca sistem. Obiect, _. Sistemul ByVal e As. EventArgs) _. Mânere btnLabelAdd. Clic. 'Apelați metoda AddNewLabel. 'din MyControlArray. MyControlArray. AddNewLabel () 'Modificați proprietatea BackColor. 'al butonului 0. MyControlArray (0) .BackColor = _. Sistem. Desen. Culoare. Roșu. Sub final. Sub Privat btnLabelRemove_Click (_. ByVal expeditor ca sistem. Obiect, _. Sistemul ByVal e As. EventArgs) _. Mânere btnLabelRemove. Clic. Apelați metoda Eliminare a MyControlArray. MyControlArray. Elimina() Sub final. Clasa finală

În primul rând, acest lucru nici măcar nu face treaba la Design Time, așa cum o făceam în VB 6! Și în al doilea rând, nu sunt într-un tablou, sunt într-o colecție VB.NET - un lucru mult diferit decât un tablou.

Motivul pentru care VB.NET nu acceptă „tabloul de control” al VB 6 este acela că nu există un „tablou” de „control” (rețineți schimbarea ghilimelelor). VB 6 creează o colecție din spatele scenei și o face să apară ca un tablou pentru dezvoltator. Dar nu este un tablou și ai prea puțin control asupra lui, dincolo de funcțiile furnizate prin IDE.

VB.NET, pe de altă parte, îl numește cum este: o colecție de obiecte. Și predau cheile regatului dezvoltatorului, creând totul în aer liber.

Ca un exemplu de tipul de avantaje pe care acesta îl oferă dezvoltatorului, în VB 6 controalele trebuiau să fie de același tip și trebuiau să aibă același nume. Deoarece acestea sunt doar obiecte în VB.NET, puteți să le faceți tipuri diferite și să le dați nume diferite și să le administrați în continuare în aceeași colecție de obiecte.

În acest exemplu, același eveniment Click gestionează două butoane și o casetă de selectare și afișează pe care a fost făcut clic. Faceți asta într-o linie de cod cu VB 6!

Sub-sub-mixt privatControls_Click (_
ByVal expeditor ca sistem. Obiect, _
Sistemul ByVal e As. EventArgs) _
Handles Button1.Click, _
Button2.Faceți clic, _
CheckBox1.Click
„Declarația de mai jos trebuie să fie o declarație lungă!
- Este pe patru rânduri aici pentru a-l îngusta
'suficient pentru a se potrivi pe o pagină web
Etichetă2.Text =
Microsoft. Visual Basic. Corect (expeditor. Gettype. ToString,
Len (expeditor. Gettype. ToString) -
(InStr (expeditor. Gettype. ToString, "Formulare") + 5))
Sub final

Calculul stratului este complex, dar nu despre ce vorbim aici. Ați putea face orice în cadrul evenimentului Click. Puteți folosi, de exemplu, tipul controlului într-o instrucțiune If pentru a face lucruri diferite pentru controale diferite.

Grupul lui Frank's Computing Studies Feedback on Srays

Grupul de studiu al lui Frank a oferit un exemplu cu un formular care are 4 etichete și 2 butoane. Butonul 1 șterge etichetele și butonul 2 le umple. Este o idee bună să citiți din nou întrebarea inițială a lui Frank și să observați că exemplul pe care l-a folosit a fost o buclă care este folosită pentru a șterge proprietatea Legătură a unei game de componente Label. Iată echivalentul VB.NET al codului VB 6. Acest cod face ceea ce Frank a cerut inițial!

Clasa publică Form1. Sistem de moștenire. Windows. Formulare. Formă. #Region „Codul generat de Windows Form Designer” Dim LabelArray (4) Ca etichetă. 'declară o serie de etichete. Sub Formular privat1_Load (_. ByVal expeditor ca sistem. Obiect, _. Sistemul ByVal e As. EventArgs) _. Gestionează MyBase. Sarcină. SetControlArray () Sub final. Sub SetControlArray () LabelArray (1) = Etichetă1. LabelArray (2) = Etichetă2. LabelArray (3) = Etichetă3. LabelArray (4) = Etichetă4. Sub final. Sub-buton privat1_Click (_. ByVal expeditor ca sistem. Obiect, _. Sistemul ByVal e As. EventArgs) _. Buton pentru mânere1.Click. 'Buton 1 Clear Array. Dim a As Integer. Pentru a = 1 până la 4. LabelArray (a) .Text = "" Următor →. Sub final. Sub-buton privat2_Click (_. ByVal expeditor ca sistem. Obiect, _. Sistemul ByVal e As. EventArgs) _. Handles Button2.Click. 'Buton 2 Completare Array. Dim a As Integer. Pentru a = 1 până la 4. LabelArray (a) .Text = _. „Array Control” și CStr (a) Următor →. Sub final. Clasa finală

Dacă experimentezi cu acest cod, vei descoperi că pe lângă setarea proprietăților Etichetelor, poți apela și la metode. Deci de ce am (și Microsoft) am trecut la toate problemele pentru a construi codul „Urât” din partea I a articolului?

Nu trebuie să fiu de acord că este într-adevăr un „control Array” în sensul clasic VB. VB 6 Control Array este o parte acceptată a sintaxei VB 6, nu doar o tehnică. De fapt, poate că modalitatea de a descrie acest exemplu este că este o serie de controale, nu o matrice de control.

În partea I, m-am plâns că exemplul Microsoft a funcționat DOAR la timpul de rulare și nu la timpul de proiectare. Puteți adăuga și șterge controale dintr-un formular în mod dinamic, dar totul trebuie să fie implementat în cod. Nu puteți trage și elimina controale pentru a le crea așa cum puteți în VB 6. Acest exemplu funcționează în principal la timpul de proiectare și nu la timpul de execuție. Nu puteți adăuga și șterge controalele în mod dinamic în timpul rulării. Într-un fel, este opusul complet al exemplului din partea I.

Exemplul clasic al tabloului de control VB 6 este același care este implementat în codul VB .NET. Aici în codul VB 6 (acesta este preluat de la Mezick & Hillier, Ghidul examenului de certificare Visual Basic 6, p 206 - ușor modificat, deoarece exemplul din carte duce la controale care nu pot fi văzute):

Dim MyTextBox ca VB.TextBox. Numărul static ca număr întreg. intNumber = intNumber + 1. Setați MyTextBox = _. Pe mine. Controale. Adăugați („VB.TextBox”, _. „Text” și număr int) MyTextBox. Text = MyTextBox. Nume. MyTextBox. Vizibil = Adevărat. MyTextBox. Stânga = _. (număr int - 1) * 1200

Dar, deoarece Microsoft (și eu) suntem de acord, tablourile de control VB 6 nu sunt posibile în VB.NET. Deci, cel mai bun lucru pe care îl puteți face este duplicarea funcționalității. Articolul meu a duplicat funcționalitatea găsită în exemplul Mezick & Hillier. Codul Grupului de studiu duplică funcționalitatea de a putea seta proprietăți și metode de apel.

Deci, linia de bază este că depinde cu adevărat de ceea ce vrei să faci. VB.NET nu are totul învelit ca parte a limbii - Cu toate acestea, dar în cele din urmă este mult mai flexibil.

Piesele de control ale lui John Fannon

John a scris: Aveam nevoie de tablouri de control pentru că voiam să pun o simplă tabelă de numere pe un formular la timpul de execuție. Nu voiam greața de a le pune pe toate individual și am vrut să folosesc VB.NET. Microsoft oferă o soluție foarte detaliată la o problemă simplă, dar este un trântor foarte mare pentru a sparge o piuliță foarte mică. După câteva experimentări, am ajuns în cele din urmă la o soluție. Iată cum am făcut-o.

Exemplul Despre Visual Basic de mai sus arată cum puteți crea un TextBox pe un formular prin crearea unei instanțe a obiectului, setarea proprietăților și adăugarea acestuia în colecția Controale care face parte din formular obiect.

Dim txtDataShow Ca New TextBox
txtDataShow. Înălțime = 19
txtDataShow. Lățime = 80
txtDataShow. Locație = Punct nou (X, Y)
Pe mine. Controale. Adăugare (txtDataShow)
Deși soluția Microsoft creează o clasă, am motivat că ar fi posibil să înfășurați toate acestea într-o subrutină. De fiecare dată când apelați această subrutină creați o nouă instanță a căsuței de text din formular. Iată codul complet:

Clasa publică Form1
Sistem de moștenire. Windows. Formulare. Formă

#Region „Codul generat de Windows Form Designer”

Subcartul privat BtnStart_Click (_
ByVal expeditor ca sistem. Obiect, _
Sistemul ByVal e As. EventArgs) _
Mânere btnStart. Clic

Dim I ca număr întreg
Dim sData ca șir
Pentru I = 1 până la 5
sData = CStr (I)
Apelați AddDataShow (sData, I)
Următor →
Sub final
SubAdăugareDatașă (_
ByVal sText As String, _
ByVal I ca întreg)

Dim txtDataShow Ca New TextBox
Dim UserLft, UserTop Ca număr întreg
Dim X, Y Ca număr întreg
UserLft = 20
UserTop = 20
txtDataShow. Înălțime = 19
txtDataShow. Latime = 25
txtDataShow. TextAlign = _
Aliniere orizontala. Centru
txtDataShow. BorderStyle = _
BorderStyle. FixedSingle
txtDataShow. Text = sText
X = Flux de utilizator
Y = UserTop + (I - 1) * txtDataShow. Înălţime
txtDataShow. Locație = Punct nou (X, Y)
Pe mine. Controale. Adăugare (txtDataShow)
Sub final
Clasa finală
Foarte bine, John. Acest lucru este cu siguranță mult mai simplu decât codul Microsoft... așa că mă întreb de ce au insistat să o facă așa?

Pentru a începe investigația noastră, să încercăm să schimbăm una dintre atribuțiile de proprietate din cod. Hai sa schimbam

txtDataShow. Înălțime = 19
la

txtDataShow. Înălțime = 100
doar pentru a vă asigura că există o diferență notabilă.

Când rulăm din nou codul, vom primi... Whaaaat??? ... același lucru. Nicio schimbare deloc. De fapt, puteți afișa valoarea cu o afirmație precum MsgBox (txtDataShow. Înălțime) și primiți în continuare 20 ca valoare a proprietății, indiferent de ce îi atribuiți. De ce se întâmplă asta?

Răspunsul este că nu derivăm propria noastră clasă pentru a crea obiectele, doar adăugăm lucruri la o altă clasă, așa că trebuie să respectăm regulile celeilalte clase. Iar aceste reguli afirmă că nu puteți schimba proprietatea Height. (Wellllll... poti. Dacă schimbați proprietatea Multiline pe True, atunci puteți modifica Înălțimea.)

De ce VB.NET merge înainte și execută codul, fără să știe măcar că ar putea să se întâmple ceva în neregulă atunci când, de fapt, nu ține cont total de afirmația dvs. este un cu totul altceva. Aș putea sugera cel puțin un avertisment în compilare, totuși. (Aluzie! Aluzie! Aluzie! Ascultă Microsoft?)

Exemplul din partea I moștenește de la o altă clasă și acest lucru face ca proprietățile să fie disponibile codului din clasa de moștenire. Modificarea proprietății înălțimii la 100 în acest exemplu ne oferă rezultatele așteptate. (Din nou... o singură exonerare: Când se creează o nouă instanță a unei componente Label mare, aceasta o acoperă pe cea veche. Pentru a vedea efectiv noile componente Label, trebuie să adăugați apelul metodei aLabel. BringToFront ().)

Acest exemplu simplu arată că, deși putem să adăugăm pur și simplu obiecte într-o altă clasă (și uneori acesta este lucrul corect), programarea controlului asupra obiectelor necesită să le derivăm într-o clasă și cel mai organizat mod (îndrăznesc să spun, „modul .NET” ??) este să creăm proprietăți și metode în noua clasă derivată pentru a schimba lucruri. John a rămas la început neconvins. El a spus că noua sa abordare se potrivește scopului său, chiar dacă există limitări de a nu fi „COO” (corect orientat pe obiecte). Mai nou, însă, John a scris,

"... după ce am scris un set de 5 cutii de text la runtime, am vrut să actualizez datele într-o parte ulterioară a programului - dar nimic nu s-a schimbat - datele originale erau încă acolo.

Am descoperit că pot rezolva problema scriind cod pentru a scoate casetele vechi și a le reface cu date noi. O modalitate mai bună de a face acest lucru ar fi să mă folosească de Mine. Reîmprospăta. Dar această problemă mi-a atras atenția asupra necesității de a furniza o metodă pentru a scădea casetele de text și pentru a le adăuga. "

Codul lui John a folosit o variabilă globală pentru a urmări câte controale au fost adăugate în formular, astfel încât o metodă ...

Sub Formular privat1_Load (_
ByVal expeditor ca sistem. Obiect, _
Sistemul ByVal e As. EventArgs) _
Gestionează MyBase. Sarcină
CntlCnt0 = Eu. Controale. Numara
Sub final

Apoi, ultimul control ar putea fi eliminat ...

N = Eu. Controale. Contele - 1
Pe mine. Controale. RemoveAt (N)
John a menționat că, „poate este un pic stângaci”.

Este modul în care Microsoft ține evidența obiectelor în COM ȘI în codul de exemplu „urât” de mai sus.

Am revenit acum la problema creării dinamice a controalelor pe un formular la timpul de execuție și m-am uitat din nou la articolele „Ce s-a întâmplat să controlăm”.

Am creat clasele și acum pot plasa controalele pe formular în modul în care vreau să fie.

Ioan a demonstrat cum să controleze plasarea controalelor într-o casetă de grup folosind noile clase pe care a început să le utilizeze. Poate că Microsoft a avut dreptate soluția lor „urâtă” la urma urmei!

instagram story viewer