VB.NET: kas notika ar masīvu vadīšanu
Kā rīkoties ar vadīklu kolekcijām VB.NET
Vadības masīvu izlaišana no VB.NET ir izaicinājums tiem, kas māca par masīviem.
- Vairs nav iespējams vienkārši kopēt vadīklu, piemēram, tekstlodziņu, un pēc tam ielīmēt to (vienu vai vairākas reizes), lai izveidotu vadīklu masīvu.
- VB.NET kods vadības masīvam līdzīgas struktūras izveidei visās VB.NET grāmatās, kuras esmu iegādājies un tiešsaistē, ir bijis daudz garāks un daudz sarežģītāks. Tam trūkst vadības masīva kodēšanas vienkāršības, kas atrodama VB6.
Ja atsaucaties uz VB6 saderības bibliotēku, tajā ir objekti, kas darbojas gandrīz kā vadības masīvi. Lai saprastu, ko es domāju, vienkārši izmantojiet VB.NET jaunināšanas vedni ar programmu, kurā ir vadības masīvs. Kods atkal ir neglīts, bet tas darbojas. Sliktā ziņa ir tā, ka Microsoft negarantēs, ka saderības komponenti arī turpmāk tiks atbalstīti, un jūs nedrīkstat tos izmantot.
VB.NET kods, lai izveidotu un izmantotu “vadības masīvus”, ir daudz garāks un daudz sarežģītāks.
Saskaņā ar Microsoft teikto, lai paveiktu kaut ko tuvu tam, ko varat darīt VB 6, ir jāizveido 'vienkāršs komponents, kas dublē vadības masīva funkcionalitāti'.
Lai to ilustrētu, ir nepieciešama gan jauna klase, gan hostinga veidlapa. Klase faktiski veido un iznīcina jaunas etiķetes. Pilns klases kods ir šāds:
Publiskās klases LabelArray
Pārmanto System.Collections.CollectionBase
Privāts ReadOnly HostForm kā _
System.Windows.Forms.Form
Publiskā funkcija AddNewLabel() _
Kā System.Windows.Forms.Label
Izveidojiet jaunu klases Label gadījumu.
Dim aLabel As New System.Windows.Forms.Label
Pievienot etiķeti kolekcijai
' iekšējais saraksts.
Es.Saraksts.Pievienot(aLabel)
' Pievienojiet etiķeti kolekcijai vadīklas
' veidlapā, uz kuru atsaucas laukā HostForm.
HostForm.Controls.Add(aLabel)
Iestatiet objekta Label sākotnējos rekvizītus.
aLabel.Top = Skaits * 25
aLabel.Width = 50
aLabel.Left = 140
aLabel.Tag = Es.Count
aLabel.Text = 'Etiķete' & Me.Count.ToString
Atgriezt aLabel
Beigu funkcija
Publisks apakš jauns(_
ByVal saimniekdators kā System.Windows.Forms.Form)
HostForm = saimniekdators
Es.Pievienot jaunu iezīmi()
Beigt apakš
Noklusējuma publiskais tikai lasāms īpašums _
Vienums (ByVal indekss kā vesels skaitlis) kā _
System.Windows.Forms.Label
gūt
Atgriezt CType(Me.List.Item(Index), _
System.Windows.Forms.Label)
Beigt Saņemt
Gala īpašums
Publisks apakšnoņemt()
Pārbaudiet, vai ir jānoņem etiķete.
Ja Me.Count > 0 Tad
Noņemiet pēdējo masīvam pievienoto etiķeti
no resursdatora formas vadīklu kolekcijas.
' Ņemiet vērā noklusējuma rekvizīta izmantošanu
' piekļūstot masīvam.
HostForm.Controls.Remove(Me(Me.Count - 1))
Es.List.RemoveAt(Es.Count — 1)
Beigas Ja
Beigt apakš
Beigu klase
Lai ilustrētu, kā šis klases kods tiks izmantots, varat izveidot veidlapu, kas to izsauc. Veidlapā jums būs jāizmanto tālāk norādītais kods:
|_+_|Pirmkārt, tas pat neveic to darbu Design Time, kā mēs to darījām VB 6! Un, otrkārt, tie nav masīvā, tie atrodas VB.NET kolekcijā — daudz kas atšķiras no masīva.
Iemesls VB.NET neatbalsta VB 6 'vadības masīvu' ir tāds, ka nav tādas lietas kā 'vadības' 'masīvs' (ņemiet vērā pēdiņu maiņu). VB 6 izveido aizkulišu kolekciju un padara to izstrādātājam par masīvu. Bet tas nav masīvs, un jums ir neliela kontrole pār to, izņemot funkcijas, ko nodrošina IDE.
No otras puses, VB.NET to sauc par to, kas tas ir: objektu kolekcija. Un viņi nodod valstības atslēgas izstrādātājam, izveidojot visu atklāti.
Kā piemēru priekšrocībām, ko tas sniedz izstrādātājam, VB 6 vadīklām bija jābūt viena veida un tām bija jābūt tādam pašam nosaukumam. Tā kā tie ir tikai VB.NET objekti, varat tos izveidot dažādu veidu un piešķirt tiem dažādus nosaukumus, kā arī pārvaldīt tos vienā objektu kolekcijā.
Šajā piemērā tas pats Click notikums apstrādā divas pogas un izvēles rūtiņu un parāda, kura no tām tika noklikšķināta. Dariet to vienā koda rindā ar VB 6!
Private Sub MixedControls_Click( _
Autors: Val sūtītājs Kā System.Object, _
ByVal e As System.EventArgs) _
Rokturu poga 1. Noklikšķiniet, _
2. poga. Noklikšķiniet, _
1. izvēles rūtiņa. Noklikšķiniet
Tālāk sniegtajam apgalvojumam ir jābūt vienam garam apgalvojumam!
Tas ir četrās rindās, lai tas būtu šaurs
' pietiekami, lai ietilptu tīmekļa lapā
Iezīme2.Teksts =
Microsoft.VisualBasic.Right(sender.GetType.ToString,
Len(sūtītājs.GetType.ToString) —
(InStr(sender.GetType.ToString, 'Veidlapas') + 5))
Beigt apakš
Apakšvirknes aprēķins ir sarežģīts, taču tas nav īsti tas, par ko mēs šeit runājam. Pasākumā Click jūs varētu darīt jebko. Varat, piemēram, izmantot vadīklas tipu If priekšrakstā, lai dažādām vadīklām veiktu dažādas darbības.
Frank's Computing Studies Group Atsauksmes par masīviem
Frank's Study Group sniedza piemēru ar veidlapu, kurā ir 4 etiķetes un 2 pogas. 1. poga notīra etiķetes, bet 2. poga tās aizpilda. Ieteicams vēlreiz izlasīt Frenka sākotnējo jautājumu un pamanīt, ka viņa izmantotais piemērs bija cilpa, kas tiek izmantota, lai notīrītu etiķetes komponentu masīva rekvizītu Caption. Šeit ir šī VB 6 koda VB.NET ekvivalents. Šis kods izpilda to, ko Frenks sākotnēji lūdza!
|_+_|
Eksperimentējot ar šo kodu, jūs atklāsiet, ka papildus etiķešu rekvizītu iestatīšanai varat izsaukt arī metodes. Tātad, kāpēc es (un Microsoft) piepūlējos, lai izveidotu neglīto kodu raksta I daļā?
Man ir jāpiekrīt, ka tas patiešām ir 'Control Array' klasiskajā VB izpratnē. VB 6 vadības masīvs ir atbalstīta VB 6 sintakses daļa, nevis tikai tehnika. Patiesībā, iespējams, veids, kā aprakstīt šo piemēru, ir tāds, ka tas ir vadīklu masīvs, nevis vadības masīvs.
Pirmajā daļā es sūdzējos, ka Microsoft piemērs darbojās TIKAI izpildes laikā, nevis projektēšanas laikā. Veidlapas vadīklas var pievienot un dzēst dinamiski, taču visa lieta ir jāievieš kodā. Jūs nevarat vilkt un nomest vadīklas, lai tās izveidotu tāpat kā VB 6. Šis piemērs darbojas galvenokārt projektēšanas laikā, nevis izpildes laikā. Jūs nevarat pievienot un dzēst vadīklas dinamiski izpildes laikā. Savā ziņā tas ir pilnīgs pretstats I daļas piemēram.
Klasiskais VB 6 vadības masīva piemērs ir tas pats, kas ir ieviests VB .NET kodā. Šeit VB 6 kodā (tas ir ņemts no Mezick & Hillier, Visual Basic 6 sertifikācijas eksāmena rokasgrāmata , 206. lpp. — nedaudz mainīts, jo grāmatas piemērā ir redzamas vadīklas):
|_+_|Bet, kā Microsoft (un es) piekrītu, VB 6 vadības bloki nav iespējami VB.NET. Tāpēc labākais, ko varat darīt, ir dublēt funkcionalitāti. Manā rakstā tika dublēta funkcionalitāte, kas atrodama piemērā Mezick & Hillier. Pētījumu grupas kods dublē rekvizītu un izsaukuma metožu iestatīšanas funkcionalitāti.
Tātad būtība ir tāda, ka tas tiešām ir atkarīgs no tā, ko vēlaties darīt. Tomēr VB.NET viss nav iekļauts kā valodas daļa, taču galu galā tas ir daudz elastīgāks.
Džona Fannona pārņemšana par kontroles masīviem
Džons rakstīja: Man bija nepieciešami vadības masīvi, jo es gribēju izpildes laikā veidlapā ievietot vienkāršu skaitļu tabulu. Es nevēlējos, lai būtu slikta dūša, ievietojot tos visus atsevišķi, un es gribēju izmantot VB.NET. Microsoft piedāvā ļoti detalizētu risinājumu vienkāršai problēmai, taču tas ir ļoti liels veseris, lai pārlauztu ļoti mazu uzgriezni. Pēc dažiem eksperimentiem es beidzot atradu risinājumu. Lūk, kā es to izdarīju.
Iepriekš sniegtajā piemērā Par Visual Basic ir parādīts, kā veidlapā var izveidot tekstlodziņu, izveidojot objekta gadījumu, iestatot rekvizītus un pievienojot to vadīklu kolekcijai, kas ir daļa no veidlapas objekta.
Aptumšot txtDataShow kā jaunu tekstlodziņu
txtDataShow.Height = 19
txtDataShow.Width = 80
txtDataShow.Location = jauns punkts(X, Y)
Es.Controls.Add(txtDataShow)
Lai gan Microsoft risinājums veido klasi, es spriedu, ka to visu varētu ietīt apakšprogrammā. Katru reizi, kad izsaucat šo apakšprogrammu, veidlapā tiek izveidots jauns tekstlodziņa gadījums. Šeit ir pilns kods:
Publiskās klases veidlapa1
Pārmanto System.Windows.Forms.Form
#Region ' Windows Form Designer ģenerēts kods'
Privāts Sub BtnStart_Click( _
Autors: Val sūtītājs Kā System.Object, _
ByVal e As System.EventArgs) _
Rokturi btnStart.Click
Dim I As Integer
Dim sData As String
Ja I = 1 līdz 5
sData = CStr(I)
Izsaukt AddDataShow(sData, I)
Nākamais
Beigt apakš
Sub AddDataShow(_
ByVal sText As String, _
Val I kā vesels skaitlis)
Aptumšot txtDataShow kā jaunu tekstlodziņu
Dim UserLft, UserTop kā vesels skaitlis
Dim X, Y Kā vesels skaitlis
UserLft = 20
UserTop = 20
txtDataShow.Height = 19
txtDataShow.Width = 25
txtDataShow.TextAlign = _
HorizontalAlignment.Centrs
txtDataShow.BorderStyle = _
BorderStyle.FixedSingle
txtDataShow.Text = sTeksts
X = UserLft
Y = UserTop + (I - 1) * txtDataShow.Height
txtDataShow.Location = jauns punkts(X, Y)
Es.Controls.Add(txtDataShow)
Beigt apakš
Beigu klase
Ļoti labs viedoklis, Džon. Tas noteikti ir daudz vienkāršāk nekā Microsoft kods ... tāpēc es brīnos, kāpēc viņi uzstāja, ka tas jādara šādā veidā?
Lai sāktu izmeklēšanu, mēģināsim mainīt kādu no īpašuma piešķīrumiem kodā. Mainīsimies
txtDataShow.Height = 19
uz
txtDataShow.Height = 100
tikai tāpēc, lai pārliecinātos, ka ir pamanāma atšķirība.
Kad mēs atkal palaižam kodu, mēs saņemam ... Whaaaat??? ... tas pats. Izmaiņu vispār nav. Faktiski jūs varat parādīt vērtību, izmantojot tādu paziņojumu kā MsgBox (txtDataShow.Height), un jūs joprojām saņemat 20 kā īpašuma vērtību neatkarīgi no tā, ko jūs tam piešķirat. Kāpēc tā notiek?
Atbilde ir tāda, ka mēs neatvasinām savu klasi, lai izveidotu objektus, mēs vienkārši pievienojam lietas citai klasei, tāpēc mums ir jāievēro citas klases noteikumi. Un šie noteikumi nosaka, ka jūs nevarat mainīt rekvizītu Height. (Nu... jūs varat. Ja maināt rekvizītu Daudzrindu uz True, varat mainīt augstumu.)
Kāpēc VB.NET iet uz priekšu un izpilda kodu, pat nežēlojot, ka var būt kaut kas nepareizs, ja patiesībā tas pilnībā neņem vērā jūsu apgalvojumu, ir vesela problēma. Tomēr es varētu ieteikt vismaz brīdinājumu apkopojumā. (Padoms! Padoms! Padoms! Vai Microsoft klausās?)
Piemērs no I daļas tiek mantots no citas klases, un tas padara rekvizītus pieejamus kodam mantotajā klasē. Mainot rekvizītu Height uz 100 šajā piemērā, mēs iegūstam gaidītos rezultātus. (Atkal ... viena atruna: kad tiek izveidots jauns liela Label komponenta gadījums, tas aizsedz veco. Lai faktiski redzētu jaunos Label komponentus, jums ir jāpievieno metodes izsaukums aLabel.BringToFront().)
Šis vienkāršais piemērs parāda, ka, lai gan mēs VARAM vienkārši pievienot objektus citai klasei (un dažreiz tas ir pareizi), objektu kontroles programmēšana prasa, lai mēs tos atvasinātu klasē un visorganizētākajā veidā (uzdrošinos teikt, '.NET veids' ??) ir izveidot rekvizītus un metodes jaunajā atvasinātajā klasē, lai mainītu lietas. Džons sākumā palika nepārliecināts. Viņš teica, ka viņa jaunā pieeja atbilst viņa mērķim, lai gan pastāv ierobežojumi, ka tas nav “COO” (pareizi objektorientēts). Tomēr pavisam nesen Džons rakstīja:
' ... pēc 5 tekstlodziņu kopas rakstīšanas izpildlaikā es gribēju atjaunināt datus nākamajā programmas daļā, taču nekas nemainījās - sākotnējie dati joprojām bija tur.
Es atklāju, ka varu apiet problēmu, ierakstot kodu, lai noņemtu vecās kastes un ievietotu tās atpakaļ ar jauniem datiem. Labāks veids, kā to izdarīt, būtu izmantot Me.Refresh. Taču šī problēma ir pievērsusi manu uzmanību nepieciešamībai nodrošināt metodi tekstlodziņu atņemšanai, kā arī to pievienošanai.
Jāņa kods izmantoja globālo mainīgo, lai izsekotu, cik vadīklas ir pievienotas veidlapai, tāpēc metode ...
Privātā apakšveidlapa1_Ielādēt(_
Autors: Val sūtītājs Kā System.Object, _
ByVal e As System.EventArgs) _
Rokturi MyBase.Load
CntlCnt0 = Es.Vadības.Count
Beigt apakš
Tad 'pēdējo' vadību varētu noņemt...
N = es. Kontroles. Skaits — 1
Me.Controls.RemoveAt(N)
Džons atzīmēja, ka 'varbūt tas ir nedaudz neveikli.'
Tas ir veids, kā Microsoft izseko objektus COM UN to “neglītajā” piemēra kodā iepriekš.
Tagad esmu atgriezies pie problēmas, kas saistīta ar veidlapas vadīklu dinamisku izveidi izpildes laikā, un esmu vēlreiz apskatījis rakstus “Kas notika ar masīvu vadīšanu”.
Esmu izveidojis klases un tagad varu novietot vadīklas veidlapā tā, kā es to vēlos.
Džons demonstrēja, kā kontrolēt vadīklu izvietošanu grupas lodziņā, izmantojot jaunās klases, kuras viņš ir sācis lietot. Varbūt Microsoft to izdarīja pareizi savā 'neglītajā' risinājumā!