VB.NET: Co się stało z tablicami kontrolnymi

click fraud protection

Pominięcie tablic kontrolnych z VB.NET stanowi wyzwanie dla osób uczących o tablicach.

  • Nie można już po prostu skopiować formantu, takiego jak pole tekstowe, a następnie wkleić go (raz lub kilka razy), aby utworzyć tablicę kontrolną.
  • Kod VB.NET do tworzenia struktury podobnej do tablicy kontrolnej był we wszystkich książkach na VB.NET, które kupiłem i przez Internet, znacznie dłużej i znacznie bardziej skomplikowany. Brakuje w nim prostoty kodowania tablicy kontrolnej, którą można znaleźć w VB6.

Jeśli odwołujesz się do biblioteki kompatybilności VB6, znajdują się tam obiekty, które działają podobnie jak tablice kontrolne. Aby zobaczyć, co mam na myśli, po prostu użyj kreatora aktualizacji VB.NET z programem zawierającym tablicę kontrolną. Kod jest znowu brzydki, ale działa. Zła wiadomość jest taka, że ​​Microsoft nie gwarantuje, że komponenty kompatybilności będą nadal obsługiwane, a ty nie powinieneś ich używać.

Kod VB.NET do tworzenia i używania „tablic kontrolnych” jest znacznie dłuższy i znacznie bardziej złożony.

instagram viewer

Według Microsoftu zrobienie czegoś nawet bliskiego temu, co można zrobić w VB 6, wymaga stworzenia „prostego komponentu, który powiela funkcjonalność tablicy kontrolnej”.

Aby to zilustrować, potrzebujesz zarówno nowej klasy, jak i formularza hostingowego. Klasa faktycznie tworzy i niszczy nowe etykiety. Pełny kod klasy jest następujący:

Klasa publiczna LabelArray
Dziedziczy system. Kolekcje CollectionBase
Prywatny ReadOnly HostForm As _
System. Windows Formularze Formularz
Funkcja publiczna AddNewLabel () _
Jako system. Windows Formularze Etykieta
„Utwórz nową instancję klasy Label.
Dim aLabel jako nowy system. Windows Formularze Etykieta
„Dodaj etykietę do kolekcji
„lista wewnętrzna.
Mnie. Lista. Dodaj (aLabel)
„Dodaj etykietę do kolekcji Controls
”formularza, do którego odwołuje się pole HostForm.
HostForm. Sterownica. Dodaj (aLabel)
„Ustaw właściwości początkowe obiektu Label.
etykieta. Top = liczba * 25
etykieta. Szerokość = 50
etykieta. Lewo = 140
etykieta. Tag = ja. Liczyć
etykieta. Text = „Label” i ja. Liczyć. ToString
Zwróć aLabel
Funkcja zakończenia
Subwoofer publiczny Nowy (_
Host ByVal jako system. Windows Formularze Formularz)
HostForm = host
Mnie. AddNewLabel ()
Napis końcowy
Domyślna publiczna właściwość ReadOnly _
Pozycja (ByVal Index As Integer) As _
System. Windows Formularze Etykieta
Otrzymać
Zwróć CType (Me. List. Pozycja (indeks), _
System. Windows Formularze Etykieta)
End Get
Zakończ właściwość
Sub publiczne usuń ()
„Sprawdź, czy istnieje etykieta do usunięcia.
Jeśli ja. Policz> 0 Następnie
„Usuń ostatnią etykietę dodaną do tablicy
„z kolekcji kontrolek formularza hosta.
„Zwróć uwagę na użycie domyślnej właściwości w
„dostęp do tablicy.
HostForm. Sterownica. Usuń (Me (Me. Count - 1))
Mnie. Lista. RemoveAt (Me. Count - 1)
End If
Napis końcowy
Klasa końcowa

Aby zilustrować sposób użycia tego kodu klasy, można utworzyć formularz, który go wywołuje. Musisz użyć kodu pokazanego poniżej w formularzu:

Formularz klasy publicznej 1. Dziedziczy system. Windows Formularze Formularz. #Region „Kod wygenerowany przez Projektanta formularzy Windows” „Ponadto należy dodać oświadczenie:„ MyControlArray = New LabelArray (Me) 'po wywołaniu InitializeComponent () w. „ukryty kod regionu. „Zadeklaruj nowy obiekt ButtonArray. Dim MyControlArray Jako LabelArray. Sub prywatny btnLabelAdd_Click (_. ByVal nadawca jako system. Obiekt, _. ByVal e As System. EventArgs) _. Obsługuje btnLabelAdd. Kliknij. „Wywołaj metodę AddNewLabel. „MyControlArray. MyControlArray. AddNewLabel () „Zmień właściwość BackColor. 'przycisku 0. MyControlArray (0) .BackColor = _. System. Rysunek. Kolor. Czerwony. Napis końcowy. Sub prywatny btnLabelRemove_Click (_. ByVal nadawca jako system. Obiekt, _. ByVal e As System. EventArgs) _. Obsługuje btnLabelRemove. Kliknij. „Wywołaj metodę Remove MyControlArray. MyControlArray. Usunąć() Napis końcowy. Klasa końcowa

Po pierwsze, nie robi to nawet pracy w czasie projektowania, tak jak robiliśmy to w VB 6! Po drugie, nie są w tablicy, są w kolekcji VB.NET - coś zupełnie innego niż tablica.

Powodem, dla którego VB.NET nie obsługuje „tablicy kontrolnej” VB 6, jest to, że nie istnieje coś takiego jak „tablica kontrolna” (zwróć uwagę na zmianę cudzysłowów). VB 6 tworzy kolekcję za kulisami i sprawia, że ​​jest wyświetlana jako tablica dla programisty. Ale to nie jest tablica i masz nad nią niewielką kontrolę poza funkcjami udostępnianymi przez IDE.

Z drugiej strony VB.NET nazywa to tym, czym jest: zbiorem obiektów. I przekazują klucze królestwa deweloperowi, tworząc wszystko od razu.

Jako przykład tego rodzaju zalet daje to deweloperowi, w VB 6 kontrole musiały być tego samego typu i musiały mieć tę samą nazwę. Ponieważ są to tylko obiekty w VB.NET, możesz tworzyć z nich różne typy, nadawać im różne nazwy i nadal zarządzać nimi w tej samej kolekcji obiektów.

W tym przykładzie to samo zdarzenie Click obsługuje dwa przyciski i pole wyboru oraz wyświetla, które z nich zostało kliknięte. Zrób to w jednym wierszu kodu z VB 6!

Private Sub MixedControls_Click (_
ByVal nadawca jako system. Obiekt, _
ByVal e As System. EventArgs) _
Uchwyty Button1.Click, _
Button2.Click, _
CheckBox1.Click
„Poniższe oświadczenie musi być jednym długim oświadczeniem!
„Jest tutaj na czterech liniach, żeby było wąsko
”wystarczająco, aby zmieścić się na stronie internetowej
Label2.Text =
Microsoft. Visual Basic. Racja (nadawca. GetType. ToString,
Len (nadawca. GetType. ToString) -
(InStr (nadawca. GetType. ToString, „Formularze”) + 5))
Napis końcowy

Obliczanie podciągów jest dość skomplikowane, ale tak naprawdę nie o tym tutaj mówimy. W wydarzeniu Click możesz zrobić wszystko. Możesz na przykład użyć typu kontrolki w instrukcji If, aby wykonać różne czynności dla różnych kontrolek.

Frank's Computing Studies Group Informacja zwrotna na temat tablic

Grupa badawcza Franka podała przykład z formularzem, który ma 4 etykiety i 2 przyciski. Przycisk 1 usuwa etykiety, a przycisk 2 je wypełnia. Dobrym pomysłem jest ponowne przeczytanie oryginalnego pytania Franka i zauważenie, że użyty przez niego przykład był pętlą, która służy do wyczyszczenia właściwości Caption tablicy składników Label. Oto odpowiednik VB.NET tego kodu VB 6. Ten kod robi to, o co Frank początkowo prosił!

Formularz klasy publicznej 1. Dziedziczy system. Windows Formularze Formularz. #Region „Kod wygenerowany przez Projektanta formularzy Windows” Dim LabelArray (4) As Label. „zadeklaruj tablicę etykiet. Prywatny formularz podrzędny1_1_ (_. ByVal nadawca jako system. Obiekt, _. ByVal e As System. EventArgs) _. Obsługuje MyBase. Załaduj. SetControlArray () Napis końcowy. Sub SetControlArray () LabelArray (1) = Label1. LabelArray (2) = Label2. LabelArray (3) = Label3. LabelArray (4) = Label4. Napis końcowy. Prywatny przycisk podrzędny1_Kliknij (_. ByVal nadawca jako system. Obiekt, _. ByVal e As System. EventArgs) _. Uchwyty Button1.Click. „Przycisk 1 Wyczyść tablicę. Dim a As Integer. Dla a = 1 do 4. LabelArray (a) .Text = "" Kolejny. Napis końcowy. Prywatny przycisk podrzędny 2_Kliknij (_. ByVal nadawca jako system. Obiekt, _. ByVal e As System. EventArgs) _. Uchwyty Button2. Kliknij. Przycisk 2 Fill Array. Dim a As Integer. Dla a = 1 do 4. LabelArray (a) .Text = _. „Tablica kontrolna” i CStr (a) Kolejny. Napis końcowy. Klasa końcowa

Jeśli eksperymentujesz z tym kodem, odkryjesz, że oprócz ustawiania właściwości etykiet, możesz także wywoływać metody. Dlaczego więc (i Microsoft) zadałem sobie tyle trudu, aby zbudować kod „brzydki” w części I tego artykułu?

Nie mogę się zgodzić, że tak naprawdę jest to „Control Array” w klasycznym sensie VB. Tablica kontrolna VB 6 jest obsługiwaną częścią składni VB 6, a nie tylko techniką. W rzeczywistości może sposobem na opisanie tego przykładu jest to, że jest to tablica kontrolek, a nie tablica kontrolna.

W części I narzekałem, że przykład Microsoft działał TYLKO w czasie wykonywania, a nie w czasie projektowania. Możesz dynamicznie dodawać i usuwać formanty z formularza, ale całość musi być zaimplementowana w kodzie. Nie możesz przeciągać i upuszczać elementów sterujących, aby utworzyć je tak, jak w VB 6. Ten przykład działa głównie w czasie projektowania, a nie w czasie wykonywania. Nie można dynamicznie dodawać i usuwać elementów sterujących w czasie wykonywania. W pewnym sensie jest to całkowite przeciwieństwo przykładu z części I.

Klasyczny przykład tablicy kontrolnej VB 6 jest tym samym, który jest zaimplementowany w kodzie VB .NET. Tutaj w kodzie VB 6 (pochodzi z Mezick & Hillier, Przewodnik do egzaminów certyfikacyjnych Visual Basic 6, p 206 - nieznacznie zmodyfikowany, ponieważ przykład w książce daje kontrolę, której nie widać):

Dim MyTextBox jako VB.TextBox. Statyczny intNumber jako liczba całkowita. intNumber = intNumber + 1. Ustaw MyTextBox = _. Mnie. Sterownica. Dodaj („VB.TextBox”, _. „Tekst” i intNumber) MyTextBox. Text = MyTextBox. Nazwa. MyTextBox. Widoczny = Prawda. MyTextBox. Lewo = _. (intNumber - 1) * 1200

Ale jak Microsoft (i ja) zgadzamy się, tablice kontrolne VB 6 nie są możliwe w VB.NET. Najlepsze co możesz zrobić, to zduplikować funkcjonalność. Mój artykuł powielał funkcjonalność znalezioną w przykładzie Mezick & Hillier. Kod grupy analitycznej powiela funkcję ustawiania właściwości i metod wywoływania.

Podsumowując, zależy to od tego, co chcesz zrobić. VB.NET nie ma całego tego pakietu jako części języka - ale - ale ostatecznie jest o wiele bardziej elastyczny.

John Fannon's Take on Control Arrays

John napisał: Potrzebowałem tablic kontrolnych, ponieważ chciałem umieścić prostą tabelę liczb w formularzu w czasie wykonywania. Nie chciałem mieć nudności umieszczania ich wszystkich indywidualnie i chciałem korzystać z VB.NET. Microsoft oferuje bardzo szczegółowe rozwiązanie prostego problemu, ale jest to bardzo duży młot do złamania bardzo małej nakrętki. Po kilku eksperymentach ostatecznie znalazłem rozwiązanie. Oto jak to zrobiłem.

Powyższy przykład programu Visual Basic pokazuje, jak utworzyć TextBox w formularzu, tworząc instancję obiektu, ustawianie właściwości i dodawanie go do kolekcji Controls, która jest częścią formularza obiekt.

Dim txtDataShow As New TextBox
txtDataShow. Wysokość = 19
txtDataShow. Szerokość = 80
txtDataShow. Lokalizacja = nowy punkt (X, Y)
Mnie. Sterownica. Dodaj (txtDataShow)
Chociaż rozwiązanie Microsoftu tworzy klasę, pomyślałem, że zamiast tego można zawinąć to wszystko w podprogram. Za każdym razem, gdy wywołujesz ten podprogram, tworzysz nowe wystąpienie pola tekstowego w formularzu. Oto pełny kod:

Formularz klasy publicznej 1
Dziedziczy system. Windows Formularze Formularz

#Region „Kod wygenerowany przez Projektanta formularzy Windows”

Sub prywatny BtnStart_Click (_
ByVal nadawca jako system. Obiekt, _
ByVal e As System. EventArgs) _
Obsługuje btnStart. Kliknij

Dim I As Integer
Dim sData As String
Dla I = 1 do 5
sData = CStr (I)
Zadzwoń do AddDataShow (sData, I)
Kolejny
Napis końcowy
Sub AddDataShow (_
ByVal sText As String, _
ByVal I As Integer)

Dim txtDataShow As New TextBox
Dim UserLft, UserTop As Integer
Dim X, Y jako liczba całkowita
UserLft = 20
UserTop = 20
txtDataShow. Wysokość = 19
txtDataShow. Szerokość = 25
txtDataShow. TextAlign = _
Wyrównanie w poziomie. Centrum
txtDataShow. BorderStyle = _
BorderStyle. FixedSingle
txtDataShow. Text = sText
X = UserLft
Y = UserTop + (I - 1) * txtDataShow. Wysokość
txtDataShow. Lokalizacja = nowy punkt (X, Y)
Mnie. Sterownica. Dodaj (txtDataShow)
Napis końcowy
Klasa końcowa
Bardzo dobra uwaga, John. Jest to z pewnością o wiele prostsze niż kod Microsoft... więc zastanawiam się, dlaczego tak nalegali?

Aby rozpocząć nasze dochodzenie, spróbujmy zmienić jedno z przypisań właściwości w kodzie. Zmieńmy się

txtDataShow. Wysokość = 19
do

txtDataShow. Wysokość = 100
aby upewnić się, że istnieje zauważalna różnica.

Kiedy ponownie uruchomimy kod, otrzymamy... Whaaaat??? ... to samo. W ogóle żadnych zmian. W rzeczywistości można wyświetlić wartość za pomocą instrukcji takiej jak MsgBox (txtDataShow. Wysokość), a nadal otrzymasz 20 jako wartość nieruchomości, bez względu na to, co do niej przypisasz. Dlaczego tak się dzieje?

Odpowiedź jest taka, że ​​nie tworzymy własnej klasy do tworzenia obiektów, po prostu dodajemy rzeczy do innej klasy, więc musimy przestrzegać zasad drugiej klasy. Reguły te stwierdzają, że nie można zmienić właściwości Wysokość. (Wellllll... możesz. Jeśli zmienisz właściwość Multiline na True, możesz zmienić Wysokość).

Dlaczego VB.NET idzie naprzód i wykonuje kod nawet bez skomlenia, że ​​może być coś nie tak, skoro w rzeczywistości całkowicie lekceważy twoje stwierdzenie, to zupełnie inna przeszkoda. Mogę jednak zasugerować przynajmniej ostrzeżenie w kompilacji. (Wskazówka! Wskazówka! Wskazówka! Czy Microsoft nasłuchuje?)

Przykład z części I dziedziczy z innej klasy, co powoduje, że właściwości są dostępne dla kodu w klasie dziedziczącej. Zmiana właściwości Wysokość na 100 w tym przykładzie daje nam oczekiwane wyniki. (Jeszcze raz... jedno zastrzeżenie: Gdy tworzone jest nowe wystąpienie dużego komponentu Label, obejmuje ono stare. Aby faktycznie zobaczyć nowe składniki Label, musisz dodać metodę call aLabel. Przesuń na wierzch().)

Ten prosty przykład pokazuje, że chociaż MOŻEMY po prostu dodawać obiekty do innej klasy (a czasem jest to właściwe), programowanie kontroli nad obiektami wymaga, abyśmy wyprowadzili je w klasie, a najbardziej zorganizowanym sposobem (ośmielę się powiedzieć „sposób .NET”?) jest tworzenie właściwości i metod w nowej klasie pochodnej w celu zmiany rzeczy Na początku John nie był przekonany. Powiedział, że jego nowe podejście odpowiada jego celowi, chociaż istnieją ograniczenia wynikające z braku bycia „COO” (poprawnie zorientowanym obiektowo). Jednak ostatnio John napisał:

"... po napisaniu zestawu 5 pól tekstowych w czasie wykonywania chciałem zaktualizować dane w kolejnej części programu - ale nic się nie zmieniło - oryginalne dane nadal tam były.

Odkryłem, że mogę obejść ten problem, pisząc kod, aby zdjąć stare skrzynki i przywrócić je ponownie z nowymi danymi. Lepszym sposobem na to byłoby użycie Mnie. Odświeżać. Ale ten problem zwrócił moją uwagę na potrzebę podania metody odejmowania i dodawania pól tekstowych ”.

Kod Johna używał zmiennej globalnej do śledzenia liczby elementów sterujących dodanych do formularza, więc metoda ...

Private Sub Form1_Load (_
ByVal nadawca jako system. Obiekt, _
ByVal e As System. EventArgs) _
Obsługuje MyBase. Załaduj
CntlCnt0 = Ja. Sterownica. Liczyć
Napis końcowy

Następnie można usunąć „ostatnią” kontrolkę ...

N = ja. Sterownica. Policz - 1
Mnie. Sterownica. RemoveAt (N)
John zauważył, że „może to trochę niezdarne”.

W ten sposób Microsoft śledzi obiekty w COM ORAZ w ich „brzydkim” przykładowym kodzie powyżej.

Teraz powróciłem do problemu dynamicznego tworzenia formantów w formularzu w czasie wykonywania i ponownie przyjrzałem się artykułom „Co się stało z tablicami kontrolnymi”.

Utworzyłem klasy i mogę teraz umieszczać kontrolki w formularzu tak, jak chcę.

John zademonstrował sposób kontrolowania umieszczania elementów sterujących w polu grupy za pomocą nowych klas, z których zaczął korzystać. Może w końcu Microsoft miał to w swoim „brzydkim” rozwiązaniu!

instagram story viewer