VB.NET: kas atsitiko valdant masyvus
Kaip tvarkyti valdiklių rinkinius VB.NET
Valdymo masyvų nepateikimas iš VB.NET yra iššūkis tiems, kurie moko apie masyvus.
- Nebegalima tiesiog nukopijuoti valdiklio, pvz., teksto laukelio, ir įklijuoti jį (vieną ar kelis kartus), kad būtų sukurtas valdymo masyvas.
- VB.NET kodas, skirtas sukurti struktūrą, panašią į valdymo masyvą, visose VB.NET knygose, kurias įsigijau ir internete, buvo daug ilgesnis ir daug sudėtingesnis. Jam trūksta valdymo masyvo kodavimo paprastumo, kuris yra VB6.
Jei nurodote VB6 suderinamumo biblioteką, joje yra objektų, kurie veikia panašiai kaip valdymo matricos. Norėdami suprasti, ką turiu omenyje, tiesiog naudokite VB.NET naujinimo vedlį su programa, kurioje yra valdymo masyvas. Kodas vėl bjaurus, bet veikia. Bloga žinia ta, kad „Microsoft“ negarantuoja, kad suderinamumo komponentai ir toliau bus palaikomi, ir jūs neturėtumėte jų naudoti.
VB.NET kodas, skirtas kurti ir naudoti „valdymo masyvus“, yra daug ilgesnis ir daug sudėtingesnis.
„Microsoft“ teigimu, norint padaryti kažką panašaus į tai, ką galite padaryti naudodami VB 6, reikia sukurti „paprastą komponentą, dubliuojantį valdymo masyvo funkcijas“.
Norėdami tai iliustruoti, jums reikia ir naujos klasės, ir prieglobos formos. Klasė iš tikrųjų kuria ir naikina naujas etiketes. Visas klasės kodas yra toks:
Viešoji klasė LabelArray
Paveldi System.Collections.CollectionBase
Privati tik skaitoma prieglobos forma kaip _
Sistema.Windows.Formos.Forma
Viešoji funkcija AddNewLabel() _
Kaip System.Windows.Forms.Label
Sukurkite naują etikečių klasės egzempliorių.
Pritemdykite etiketę kaip naują sistemą.Windows.Forms.Label
Pridėkite etiketę prie kolekcijos
“ vidinis sąrašas.
Aš.Sąrašas.Pridėti (etiketė)
' Pridėkite etiketę prie valdiklių rinkinio
' formos, nurodytos lauke „HostForm“.
HostForm.Controls.Add(aLabel)
' Nustatykite pradines etiketės objekto ypatybes.
aLabel.Top = Skaičiavimas * 25
aEtiketė.Plotis = 50
aEtiketė.Kairė = 140
aLabel.Tag = Aš.Skaičius
aLabel.Text = 'Etiketė' & Me.Count.ToString
Grąžinti etiketę
Pabaigos funkcija
Viešas sub Naujas(_
ByVal priegloba kaip System.Windows.Forms.Form)
HostForm = šeimininkas
Aš.Pridėti naują etiketę ()
Pabaigos sub
Numatytoji viešoji tik skaitoma nuosavybė _
Elementas (ByVal indeksas kaip sveikasis skaičius) kaip _
System.Windows.Forms.Label
Gauk
Grąžinti CType(Me.List.Item(Index), _
System.Windows.Forms.Label)
Pabaiga Gauti
Pabaigos nuosavybė
Viešas sub Pašalinti ()
Patikrinkite, ar yra etiketė, kurią norite pašalinti.
Jei aš.Skaičius > 0 Tada
Pašalinkite paskutinę prie masyvo pridėtą etiketę
' iš prieglobos formos valdiklių rinkinio.
Atkreipkite dėmesį į numatytosios nuosavybės naudojimą
' prieiga prie masyvo.
HostForm.Controls.Remove(Me(Me.Count – 1))
Aš.Sąrašas.Pašalinti(Me.Count – 1)
Pabaiga Jei
Pabaigos sub
Pabaigos klasė
Norėdami parodyti, kaip šis klasės kodas būtų naudojamas, galite sukurti formą, kuri jį iškviečia. Turėtumėte naudoti toliau pateiktą kodą formoje:
|_+_|Pirma, tai net neatlieka tokio darbo „Design Time“, kaip mes tai darydavome VB 6! Antra, jie yra ne masyve, o VB.NET kolekcijoje – tai daug kas skiriasi nuo masyvo.
Priežastis, dėl kurios VB.NET nepalaiko VB 6 „valdymo masyvo“, yra ta, kad nėra tokio dalyko kaip „valdymo“ „masyvo“ (atkreipkite dėmesį į kabučių pasikeitimą). VB 6 sukuria užkulisių kolekciją ir leidžia kūrėjui atrodyti kaip masyvas. Tačiau tai nėra masyvas ir jūs mažai jį valdote, išskyrus IDE teikiamas funkcijas.
Kita vertus, VB.NET tai vadina tuo, kas yra: objektų kolekcija. Ir jie perduoda karalystės raktus kūrėjui, sukurdami viską atvirai.
Kaip pavyzdį, kokių pranašumų tai suteikia kūrėjui, VB 6 valdikliai turėjo būti to paties tipo ir turėti tą patį pavadinimą. Kadangi tai tik objektai VB.NET, galite juos sukurti skirtingų tipų ir suteikti jiems skirtingus pavadinimus ir vis tiek tvarkyti juos tame pačiame objektų rinkinyje.
Šiame pavyzdyje tas pats paspaudimo įvykis apdoroja du mygtukus ir žymimąjį laukelį bei parodo, kuris iš jų buvo spustelėtas. Padarykite tai vienoje kodo eilutėje su VB 6!
Private Sub MixedControls_Click( _
Autorius Val siuntėjas Kaip System.Object, _
ByVal e As System.EventArgs) _
Rankenėlių mygtukas1. Spustelėkite, _
2 mygtukas. Spustelėkite, _
1 žymimasis laukelis. Spustelėkite
Žemiau esantis teiginys turi būti vienas ilgas teiginys!
Čia yra keturios eilutės, kad būtų siaura
Pakanka, kad tilptų į tinklalapį
Etiketė2.Tekstas =
Microsoft.VisualBasic.Right(sender.GetType.ToString,
Len(sender.GetType.ToString) –
(InStr(sender.GetType.ToString, 'Forms') + 5))
Pabaigos sub
Poeilutės skaičiavimas yra sudėtingas, tačiau čia ne apie tai kalbame. „Click“ renginyje galite padaryti bet ką. Pavyzdžiui, galite naudoti valdiklio tipą If sakinyje, kad atliktumėte skirtingus veiksmus skirtingiems valdikliais.
Frank's Computing Studies Group atsiliepimai apie masyvus
Frank's Study Group pateikė pavyzdį su forma, kurioje yra 4 etiketės ir 2 mygtukai. 1 mygtukas išvalo etiketes, o mygtukas 2 užpildo jas. Pravartu dar kartą perskaityti pirminį Franko klausimą ir pastebėti, kad jo naudojamas pavyzdys buvo ciklas, naudojamas etiketės komponentų masyvo savybei Antraštė išvalyti. Štai VB.NET to VB 6 kodo atitikmuo. Šis kodas atlieka tai, ko Frankas iš pradžių prašė!
|_+_|
Jei eksperimentuosite su šiuo kodu, pamatysite, kad be etikečių savybių nustatymo galite iškviesti metodus. Taigi kodėl aš (ir „Microsoft“) stengiausi sukurti „bjaurų“ kodą straipsnio I dalyje?
Turiu nesutikti, kad tai iš tikrųjų yra „Control Array“ klasikine VB prasme. VB 6 valdymo masyvas yra palaikoma VB 6 sintaksės dalis, o ne tik technika. Tiesą sakant, galbūt šį pavyzdį galima apibūdinti taip, kad tai yra valdiklių masyvas, o ne valdymo masyvas.
I dalyje skundžiausi, kad Microsoft pavyzdys veikė TIK vykdymo, o ne projektavimo metu. Galite dinamiškai pridėti ir ištrinti formos valdiklius, tačiau visa tai turi būti įgyvendinta kode. Negalite nuvilkti valdiklių, kad juos sukurtumėte, kaip tai darote VB 6. Šis pavyzdys daugiausia veikia projektavimo, o ne vykdymo metu. Negalite dinamiškai pridėti ir ištrinti valdiklių vykdymo metu. Tam tikra prasme tai visiškai priešinga I dalies pavyzdžiui.
Klasikinis VB 6 valdymo masyvo pavyzdys yra tas pats, kuris įdiegtas VB .NET kode. Čia VB 6 kode (tai paimta iš Mezick & Hillier, Visual Basic 6 sertifikavimo egzamino vadovas , p. 206 – šiek tiek pakeista, nes knygoje pateiktas pavyzdys rodo valdiklius, kurių nematyti):
|_+_|Bet kaip Microsoft (ir aš) sutinku, VB 6 valdymo masyvai VB.NET neįmanomi. Taigi geriausia, ką galite padaryti, tai dubliuoti funkcijas. Mano straipsnis dubliavo „Mezick & Hillier“ pavyzdyje esančias funkcijas. Tyrimo grupės kodas dubliuoja ypatybių nustatymo ir iškvietimo metodų funkciją.
Taigi esmė ta, kad tai tikrai priklauso nuo to, ką norite daryti. Vis dėlto VB.NET nėra kalbos dalis, tačiau galiausiai ji yra daug lankstesnė.
Johno Fannono „Control Arrays“.
Jonas rašė: Man reikėjo valdymo masyvų, nes norėjau pateikti paprastą skaičių lentelę formoje vykdymo metu. Nenorėjau, kad pykintų juos visus sudėti atskirai ir norėjau naudoti VB.NET. „Microsoft“ siūlo labai išsamų paprastos problemos sprendimą, tačiau tai labai didelis plaktukas nulaužti labai mažą veržlę. Po kai kurių eksperimentų galiausiai radau sprendimą. Štai kaip aš tai padariau.
Aukščiau pateiktame pavyzdyje Apie Visual Basic parodyta, kaip formoje galite sukurti teksto laukelį, sukurdami objekto egzempliorių, nustatydami ypatybes ir įtraukdami jį į valdiklių rinkinį, kuris yra formos objekto dalis.
Pritemdyti txtDataShow kaip naują teksto laukelį
txtDataShow.Height = 19
txtDataShow.Width = 80
txtDataShow.Location = naujas taškas (X, Y)
Aš.Controls.Add(txtDataShow)
Nors „Microsoft“ sprendimas sukuria klasę, samprotavau, kad būtų galima visa tai apvilkti paprograme. Kiekvieną kartą, kai iškviečiate šią paprogramę, formoje sukuriate naują teksto laukelio egzempliorių. Štai visas kodas:
Viešosios klasės 1 forma
Paveldi System.Windows.Forms.Form
#Region „Windows Form Designer sugeneruotas kodas“
Privatus sub BtnStart_Click( _
Autorius Val siuntėjas Kaip System.Object, _
ByVal e As System.EventArgs) _
Rankenos btnStart.Spustelėkite
Dim I As Integer
Pritemdyti sData kaip eilutę
Jei I = nuo 1 iki 5
sData = CStr(I)
Skambinti AddDataShow(sData, I)
Kitas
Pabaigos sub
Sub AddDataShow(_
ByVal sText As String, _
Val I kaip sveikasis skaičius)
Pritemdyti txtDataShow kaip naują teksto laukelį
Dim UserLft, UserTop kaip sveikasis skaičius
Dim X, Y kaip sveikasis skaičius
UserLft = 20
UserTop = 20
txtDataShow.Height = 19
txtDataShow.Width = 25
txtDataShow.TextAlign = _
HorizontalusIšlygiavimas.Centras
txtDataShow.BorderStyle = _
BorderStyle.FixedSingle
txtDataShow.Text = sText
X = UserLft
Y = UserTop + (I - 1) * txtDataShow.Height
txtDataShow.Location = naujas taškas (X, Y)
Aš.Controls.Add(txtDataShow)
Pabaigos sub
Pabaigos klasė
Labai geras pastebėjimas, Jonai. Tai tikrai daug paprasčiau nei „Microsoft“ kodas... todėl įdomu, kodėl jie primygtinai reikalavo tai padaryti?
Norėdami pradėti tyrimą, pabandykime pakeisti vieną iš nuosavybės priskyrimų kode. Pasikeiskime
txtDataShow.Height = 19
į
txtDataShow.Height = 100
tik norėdami įsitikinti, kad skirtumas yra pastebimas.
Kai paleidžiame kodą dar kartą, gauname ... Whaaaat??? ... Tas pats. Jokių pokyčių. Tiesą sakant, vertę galite rodyti naudodami teiginį, pvz., MsgBox (txtDataShow.Height), ir vis tiek gausite 20 kaip nuosavybės vertę, nesvarbu, ką jai priskirsite. Kodėl taip atsitinka?
Atsakymas yra tas, kad mes nesukuriame savo klasės, kad sukurtume objektus, mes tiesiog įtraukiame dalykus į kitą klasę, todėl turime laikytis kitos klasės taisyklių. Ir tose taisyklėse nurodoma, kad jūs negalite keisti aukščio savybės. (Na, jūs galite. Jei pakeisite ypatybę „Multiline“ į „True“, galėsite pakeisti aukštį.)
Kodėl VB.NET eina į priekį ir vykdo kodą net neinkštint, kad gali būti kažkas negerai, nors iš tikrųjų visiškai nepaiso jūsų teiginio, yra visiškai „kitaip“. Vis dėlto galėčiau pasiūlyti bent įspėjimą kompiliacijoje. (Užuomina! Užuomina! Užuomina! Ar „Microsoft“ klauso?)
I dalies pavyzdys paveldimas iš kitos klasės, todėl ypatybės tampa prieinamos paveldinčios klasės kodui. Šiame pavyzdyje pakeitus savybę Aukštis į 100 gaunami laukiami rezultatai. (Vėl... vienas atsakomybės atsisakymas: kai sukuriamas naujas didelio etikečių komponento egzempliorius, jis uždengia senąjį. Norėdami iš tikrųjų pamatyti naujus etiketės komponentus, turite pridėti metodo iškvietimą aLabel.BringToFront().)
Šis paprastas pavyzdys rodo, kad nors mes GALIME tiesiog pridėti objektus į kitą klasę (o kartais tai yra teisingas dalykas), norint programuoti objektų valdymą, reikia, kad juos gautume klasėje ir labiausiai organizuotu būdu (drįsčiau pasakyti, '.NET būdas' ??) yra sukurti ypatybes ir metodus naujoje išvestinėje klasėje, kad pakeistumėte dalykus. Jonas iš pradžių liko neįtikintas. Jis sakė, kad jo naujas požiūris atitinka jo tikslą, net jei nėra „COO“ (teisingai orientuoto į objektą) apribojimų. Tačiau visai neseniai Jonas rašė:
' ... vykdymo metu parašęs 5 teksto laukelių rinkinį, norėjau atnaujinti duomenis kitoje programos dalyje – bet niekas nepasikeitė – pirminiai duomenys vis dar buvo.
Radau, kad galiu išspręsti problemą parašydamas kodą, kad nuimtų senas dėžutes ir vėl padėtų jas su naujais duomenimis. Geresnis būdas tai padaryti būtų naudoti Me.Refresh. Tačiau ši problema atkreipė mano dėmesį į poreikį pateikti metodą, kaip atimti teksto laukelius ir juos pridėti.
Jono kodas naudojo visuotinį kintamąjį, kad stebėtų, kiek valdiklių buvo pridėta prie formos, todėl metodas ...
Privati sub Form1_Load(_
Autorius Val siuntėjas Kaip System.Object, _
ByVal e As System.EventArgs) _
Valdo MyBase.Load
CntlCnt0 = Aš.Kontrolės.Skaičius
Pabaigos sub
Tada „paskutinis“ valdiklis gali būti pašalintas...
N = aš. Valdikliai. Skaičius – 1
Aš.Controls.RemoveAt(N)
Jonas pažymėjo, kad „gal tai šiek tiek gremėzdiška“.
Tai yra būdas „Microsoft“ sekti objektus COM IR aukščiau pateiktame „bjauraus“ kodo pavyzdyje.
Dabar grįžau prie dinamiško formos valdiklių kūrimo vykdymo metu problemos ir dar kartą peržiūrėjau straipsnius „Kas atsitiko su masyvų valdymu“.
Sukūriau klases ir dabar galiu įdėti valdiklius į formą taip, kaip noriu.
Jonas pademonstravo, kaip valdyti valdiklių išdėstymą grupės langelyje naudojant naujas klases, kurias pradėjo naudoti. Galbūt „Microsoft“ tai padarė teisingai savo „bjauriu“ sprendimu!