Izpuščanje kontrolnih nizov iz VB.NET je izziv za tiste, ki poučujejo o nizih.
- Ni več mogoče preprosto kopirati nadzora, kot je besedilno polje, in ga nato (enkrat ali večkrat) prilepiti, da ustvarite kontrolni niz.
- Koda VB.NET za ustvarjanje strukture, podobne kontrolnemu nizu, je bila v vseh knjigah na VB.NET, ki sem jih kupil in na spletu, veliko daljša in veliko bolj zapletena. Manjka preprostost kodiranja kontrolnega niza, ki ga najdemo v VB6.
Če omenjate knjižnico združljivosti VB6, so tam predmeti, ki delujejo podobno kot kontrolni nizi. Če želite videti, kaj mislim, preprosto uporabite čarovnika za nadgradnjo VB.NET s programom, ki vsebuje kontrolni niz. Koda je spet grda, vendar deluje. Slaba novica je, da Microsoft ne bo zagotovil, da bodo komponente združljivosti še naprej podprte in jih ne bi smeli uporabljati.
Koda VB.NET za ustvarjanje in uporabo "nadzornih nizov" je veliko daljša in veliko bolj zapletena.
Po Microsoftovem mnenju je za izdelavo nečesa, kar je podobno tistemu, kar lahko naredite v VB 6, ustvariti "preprosto komponento, ki podvaja funkcionalnost kontrolnega niza."
Za ponazoritev tega potrebujete nov razred in obrazec za gostovanje. Razred dejansko ustvarja in uničuje nove etikete. Celotna koda razreda je naslednja:
Javni razred LabelArray
Sistem dedovanja. Zbirke. CollectionBase
Zasebno bralno obliko ReadOnly As _
Sistem. Windows. Obrazci. Oblika
Javna funkcija AddNewLabel () _
Kot sistem. Windows. Obrazci. Oznaka
'Ustvari nov primerek razreda Label.
Dim aLabel kot nov sistem. Windows. Obrazci. Oznaka
„Dodaj oznako zbirkam
"notranji seznam.
Jaz. Seznam. Dodaj (oznaka)
'Dodajte oznako v zbirko Kontrolniki
"obrazca, na katerega se nanaša polje HostForm.
HostForm Kontrole. Dodaj (oznaka)
'Nastavite začetne lastnosti predmeta Label.
aLabel. Na vrh = Število * 25
aLabel. Širina = 50
aLabel. Levo = 140
aLabel. Oznaka = jaz. Štet
aLabel. Text = "Oznaka" in jaz. Štet. ToString
Vrni oznako
Končna funkcija
Javno pod novo (_
ByVal gostitelj kot sistem. Windows. Obrazci. Oblika)
HostForm = gostitelj
Jaz. AddNewLabel ()
Končni pod
Privzeta javna lastnost ReadOnly _
Postavka (ByVal indeks kot celo število) Kot _
Sistem. Windows. Obrazci. Oznaka
Pridite
Vrni CType (meni. Seznam. Postavka (kazalo), _
Sistem. Windows. Obrazci. Oznaka)
Končaj Get
Končna lastnost
Javna podstrani odstranjevanje ()
"Preverite, ali je nalepka, ki jo je treba odstraniti.
Če jaz. Štetje> 0 Nato
'Odstranite zadnjo oznako, dodano v matriko
"iz zbirke kontrolnikov obrazca gostitelja.
"Upoštevajte uporabo privzete lastnosti v
'dostop do matrike.
HostForm Kontrole. Odstrani (Jaz (Število mene - 1))
Jaz. Seznam. RemoveAt (Število me - 1)
Konec Če
Končni pod
Končni razred
Za ponazoritev uporabe te kode razreda lahko ustvarite obrazec, ki ga kliče. V obrazcu bi morali uporabiti kodo, prikazano spodaj:
Oblika javnega razreda1. Sistem dedovanja. Windows. Obrazci. Oblika. #Region "Koda, ustvarjena s strani oblikovalca obrazcev Windows" 'Prav tako morate dodati izjavo:' MyControlArray = Nov LabelArray (Me) "po klicu InitializeComponent () v. "skrita koda regije 'Razglasite nov predmet ButtonArray. Dim MyControlArray Kot LabelArray. Zasebni pod btnLabelAdd_Click (_. ByVal pošiljatelj kot sistem. Predmet, _. ByVal e As System. EventArgs) _. Ročaji btnLabelAdd. Kliknite. "Pokličite metodo AddNewLabel. 'MyControlArray. MyControlArray. AddNewLabel () 'Spremenite lastnost BackColor. "gumba 0. MyControlArray (0) .BackColor = _. Sistem. Risba. Barva. Rdeča. Končni pod. Zasebni Sub btnLabelRemove_Click (_. ByVal pošiljatelj kot sistem. Predmet, _. ByVal e As System. EventArgs) _. Ročaji btnLabelRemove. Kliknite. "Pokličite metodo Odstrani MyControlArray. MyControlArray. Odstrani() Končni pod. Končni razred
Prvič, to sploh ne opravi naloge v času načrtovanja, kot smo ga delali v VB 6! In drugič, niso v matriki, ampak v zbirki VB.NET - precej drugačna stvar od matrike.
Razlog, da VB.NET ne podpira VB 6 "kontrolne matrike" je, da ne obstaja "kontrolna matrika" (upoštevajte spremembo narekovajev). VB 6 ustvari zbirko v zakulisju in jo prikazuje kot niz razvijalca. Vendar to ni niz in imate malo nadzora nad njim nad funkcijami, ki jih zagotavlja IDE.
VB.NET ga po drugi strani imenuje, kar je: zbirka predmetov. Ključe kraljestva predajo razvijalcu, tako da celotno stvar ustvarijo na prostem.
Kot primer prednosti, ki jih to daje razvijalcu, so morali v VB 6 upravljati iste vrste in imeti isto ime. Ker so to samo predmeti v VB.NET-u, jih lahko naredite različne vrste in jim daste različna imena ter jih še vedno upravljate v isti zbirki predmetov.
V tem primeru isti dogodek Click obravnava dva gumba in potrditveno polje ter prikaže, na katerega je bil kliknjen. To storite v eni vrstici kode z VB 6!
Zasebni podmešani kontrolniki_klik (_
ByVal pošiljatelj kot sistem. Predmet, _
ByVal e As System. EventArgs) _
Ročaji s tipko1.Klik, _
Gumb2.Click, _
CheckBox1.Click
„Spodnja izjava mora biti ena dolga izjava!
"Tu je v štirih vrsticah, da ostane ozko
'dovolj, da se prilega na spletno stran
Oznaka2.Text =
Microsoft. Visual basic. Prav (pošiljatelj). GetType ToString,
Len (pošiljatelj. GetType ToString) -
(InStr (pošiljatelj) GetType ToString, "Obrazci") + 5))
Končni pod
Izračun pod vrsticami je nekako zapleten, vendar v resnici ne govorimo o tem. V dogodku Klik lahko storite karkoli. Na primer, lahko uporabite tip nadzora v stavku If, če želite narediti različne stvari za različne kontrole.
Frank's Group Computing Studies, povratne informacije o array
Frankova študijska skupina je dala primer z obrazcem, ki ima 4 nalepke in 2 gumba. Gumb 1 počisti nalepke, gumb 2 pa jih napolni. Dobro je znova prebrati Frankovo izvirno vprašanje in opaziti, da je primer, ki ga je uporabil, zanka, ki se uporablja za čiščenje lastnosti Caption iz matrike komponent Label. Tukaj je ekvivalent VB.NET te kode VB 6. Ta koda naredi tisto, kar je Frank prvotno zahteval!
Oblika javnega razreda1. Sistem dedovanja. Windows. Obrazci. Oblika. #Region "Koda, ustvarjena s strani oblikovalca obrazcev Windows" Dim LabelArray (4) Kot oznaka. 'proglasi niz nalepk. Zasebni podoblik1_Load (_. ByVal pošiljatelj kot sistem. Predmet, _. ByVal e As System. EventArgs) _. Rokuje MyBase. Obremenite. SetControlArray () Končni pod. Pod SetControlArray () LabelArray (1) = Label1. LabelArray (2) = Label2. LabelArray (3) = Label3. LabelArray (4) = Label4 Končni pod. Zasebni pod gumb1_Click (_. ByVal pošiljatelj kot sistem. Predmet, _. ByVal e As System. EventArgs) _. Ročaji s tipko1.Klik. 'Gumb 1 Počisti matriko. Dim a kot celoten. Za a = 1 do 4. LabelArray (a) .Text = "" Naslednji. Končni pod. Zasebni pod gumb2_Click (_. ByVal pošiljatelj kot sistem. Predmet, _. ByVal e As System. EventArgs) _. Ročaji gumba2.Klikni. "Gumb 2 Izpolnite matriko. Dim a kot celoten. Za a = 1 do 4. LabelArray (a) .Text = _. "Nadzorni niz" in CStr (a) Naslednji. Končni pod. Končni razred
Če eksperimentirate s to kodo, boste ugotovili, da lahko poleg nastavitve lastnosti nalepk pokličete tudi načine. Zakaj sem torej (in Microsoft) šel v vse težave, da sem sestavil kodo "Ugly" v prvem delu članka?
Moram se strinjati, da gre res za "Control Array" v klasičnem VB smislu. VB 6 Control Array je podprt del skladbe VB 6, ne le tehnika. V resnici je morda način za opis tega primera to, da gre za niz kontrol, ne pa kontrolni niz.
V prvem delu sem se pošalil, da je Microsoftov primer SAMO deloval v času izvajanja in ne v času načrtovanja. Kontrole lahko dodate in izbrišete iz obrazca dinamično, vendar mora biti celotna stvar izvedena v kodi. Nadzorov ne morete povleči in spustiti, da jih ustvarite tako, kot lahko v VB 6 Ta primer deluje predvsem v času načrtovanja in ne v času izvajanja. Kontrole ne morete dinamično dodajati in brisati. Na nek način je popolno nasprotje primera I. dela.
Primer klasičnega VB 6 kontrolnega niza je enak tistemu, ki je implementiran v kodo VB .NET. Tukaj v kodi VB 6 (ta je vzeta iz Mezick & Hillier, Vodnik po izpitu za Visual Basic 6, str. 206 - rahlo spremenjeno, saj primer v knjigi vodi do kontrol, ki jih ni mogoče videti):
Zatemnite MyTextBox kot VB.TextBox. Statični intNumber kot celoten. intNumber = intNumber + 1. Nastavite MyTextBox = _. Jaz. Kontrole. Dodaj ("VB.TextBox", _. "Besedilo" in intNumber) MyTextBox. Besedilo = MyTextBox. Ime. MyTextBox. Vidno = res. MyTextBox. Levo = _. (intNumber - 1) * 1200
Toda kot se Microsoft (in jaz) strinjam, kontrolni nizi VB 6 v VB.NET niso možni. Najboljše, kar lahko storite, je podvojitev funkcionalnosti. Moj članek je podvojil funkcionalnost, ki jo najdemo v primeru Mezick & Hillier. Koda študijske skupine podvaja funkcionalnost nastavitve lastnosti in načinov klica.
Bistvo je torej, da je res odvisno od tega, kaj želite storiti. VB.NET nima vsega, kar je zajeto kot del jezika - vendar - navsezadnje je veliko bolj prilagodljiv.
John Fannon prevzame kontrolne matrike
John je zapisal: Potreboval sem nadzorne matrike, ker sem želel na čas vstaviti preprosto tabelo števil na obrazec. Nisem želel slabosti, da bi jih vse posadil posebej, in hotel sem uporabljati VB.NET. Microsoft ponuja zelo podrobno rešitev preprostega problema, vendar je zelo velik klanec, da bi polomil zelo majhno matico. Po nekaj eksperimentiranjih sem na koncu našel rešitev. Takole sem naredil.
Zgornji primer About Visual Basic prikazuje, kako lahko ustvarite TextBox na obrazcu z ustvarjanjem primerka objekta, nastavitev lastnosti in dodajanje v zbirko Controls, ki je del obrazca objekt.
Dim txtDataShow As New TextBox
txtDataShow. Višina = 19
txtDataShow. Širina = 80
txtDataShow. Lokacija = nova točka (X, Y)
Jaz. Kontrole. Dodaj (txtDataShow)
Čeprav Microsoftova rešitev ustvarja razred, sem pomislil, da bi bilo mogoče vse to zaviti v podprogram. Vsakič, ko pokličete to podprogramo, ustvarite nov primerek besedilnega polja na obrazcu. Tu je celotna koda:
Oblika javnega razreda1
Sistem dedovanja. Windows. Obrazci. Oblika
#Region "Koda, ustvarjena s strani oblikovalca obrazcev Windows"
Zasebni Sub BtnStart_Click (_
ByVal pošiljatelj kot sistem. Predmet, _
ByVal e As System. EventArgs) _
Ročaji btnStart. Kliknite
Dim I kot celoten
Dim sData kot niz
Za I = 1 do 5
sData = CStr (I)
Pokliči AddDataShow (sData, I)
Naslednji
Končni pod
Pod AddDataShow (_
ByVal sText As String, _
ByVal I kot celoten uporabnik)
Dim txtDataShow As New TextBox
Dim UserLft, UserTop kot celoten
Dim X, Y kot celoten
UporabnikLft = 20
UserTop = 20
txtDataShow. Višina = 19
txtDataShow. Širina = 25
txtDataShow. TextAlign = _
Vodoravna prilagoditev. Center
txtDataShow. BorderStyle = _
BorderStyle. FixedSingle
txtDataShow. Text = sText
X = uporabnikLft
Y = UserTop + (I - 1) * txtDataShow. Višina
txtDataShow. Lokacija = nova točka (X, Y)
Jaz. Kontrole. Dodaj (txtDataShow)
Končni pod
Končni razred
Zelo dobro, John. To je gotovo veliko bolj preprosto kot Microsoftova koda... zato me zanima, zakaj so vztrajali pri tem tako?
Za začetek naše preiskave poskusimo spremeniti eno od lastnosti lastnosti v kodi. Spremenimo se
txtDataShow. Višina = 19
do
txtDataShow. Višina = 100
samo zato, da se prepričamo, da je opazna razlika.
Ko ponovno zaženemo kodo, dobimo... Whaaaat??? ... ista stvar. Brez sprememb sploh. V bistvu lahko vrednost prikažete z izjavo, kot je MsgBox (txtDataShow). Višina) in še vedno dobite 20 kot vrednost lastnosti, ne glede na to, kaj ji dodelite. Zakaj se to zgodi?
Odgovor je, da ne ustvarjamo lastnega razreda za ustvarjanje predmetov, ampak samo dodajamo stvari v drug razred, zato moramo upoštevati pravila drugega razreda. In ta pravila navajajo, da lastnosti Height ne morete spremeniti. (Wellllll... ti lahko. Če spremenite lastnost Multiline v True, potem lahko spremenite višino.)
Zakaj VB.NET nadaljuje in izvrši kodo, ne da bi prišepetal, da je morda nekaj narobe, če v resnici popolnoma ne upošteva vaše izjave, je povsem „nič drugega. Lahko pa predlagam vsaj opozorilo v prevajalniku. (Namig! Namig! Namig! Ali Microsoft posluša?)
Primer iz dela I podeduje iz drugega razreda, zaradi česar so lastnosti na voljo kodi v dednem razredu. Če v tem primeru spremenimo lastnost Height na 100, dobimo pričakovane rezultate. (Ponovno... eno odpoved odgovornosti: Ko je ustvarjen nov primerek velike komponente Label, prikriva stari. Če želite dejansko videti nove komponente oznake, morate dodati metodo klic aLabel. BringToFront ().)
Ta preprost primer kaže, da čeprav lahko preprosto dodajamo predmete v drug razred (in včasih je to prav), programiranje nadzora nad predmeti zahteva, da jih izpeljemo v razredu in na najbolj organiziran način (upam si reči, "način .NET" ??) je ustvariti lastnosti in metode v novem izpeljanem razredu, ki jih želimo spremeniti stvari. John je sprva ostal neprepričan. Dejal je, da njegov novi pristop ustreza njegovemu namenu, čeprav obstajajo omejitve, da ne bi bil "COO" (pravilno usmerjen). Pred kratkim pa je John napisal,
"... po pisanju niza 5 besedilnih polj med izvajanjem sem želel podatke posodobiti v naslednjem delu programa - vendar se ni nič spremenilo - izvirni podatki so še vedno obstajali.
Ugotovil sem, da lahko težavo odpravim tako, da napišem kodo, da odstranim stare škatle in jih spet dam nazaj z novimi podatki. Boljši način, da to storite, bi bila uporaba Me. Osveži. Toda ta težava je pritegnila mojo pozornost, da moram priskrbeti metodo za odštevanje besedilnih polj in njihovo dodajanje. "
Janezova koda je uporabila globalno spremenljivko, s katero je spremljala, koliko kontrol je bilo dodanih v obrazec, tako da je metoda ...
Zasebni podoblik1_Load (_
ByVal pošiljatelj kot sistem. Predmet, _
ByVal e As System. EventArgs) _
Rokuje MyBase. Obremenite
CntlCnt0 = Jaz. Kontrole. Štet
Končni pod
Potem bi "zadnji" nadzor lahko odstranili ...
N = jaz. Kontrole. Štetje - 1
Jaz. Kontrole. RemoveAt (N)
John je ugotovil, da "je to morda nekoliko nerodno."
Microsoft tako nadzira predmete v COM IN v zgornjem "grdem" primeru.
Zdaj sem se vrnil k problemu dinamičnega ustvarjanja kontrol na obrazcu v času izvajanja in ponovno sem preučil članke "Kaj se je zgodilo z nadzornimi nizi".
Ustvaril sem razrede in zdaj lahko kontrolnike postavim v obrazec tako, kot želim.
John je pokazal, kako nadzira namestitev kontrol v skupinsko polje z novimi razredi, ki jih je začel uporabljati. Mogoče je imel Microsoft navsezadnje prav v njihovi "grdi" rešitvi!