مثير للإعجاب

VB.NET: ما حدث للتحكم في المصفوفات

VB.NET: ما حدث للتحكم في المصفوفات

يمثل إغفال صفائف التحكم من VB.NET تحديًا لأولئك الذين يقومون بالتدريس حول المصفوفات.

  • لم يعد من الممكن ببساطة نسخ عنصر تحكم ، مثل مربع نص ، ثم لصقه (مرة واحدة أو عدة مرات) لإنشاء صفيف تحكم.
  • رمز VB.NET لإنشاء بنية مشابهة لصفيف التحكم كان ، في جميع الكتب على VB.NET التي اشتريتها وعبر الإنترنت ، أطول بكثير وأكثر تعقيدًا. يفتقر إلى بساطة ترميز صفيف تحكم موجود في VB6.

إذا قمت بالإشارة إلى مكتبة توافق VB6 ، فهناك كائنات تعمل بشكل يشبه إلى حد كبير صفائف التحكم. لمعرفة ما أقصده ، ما عليك سوى استخدام معالج ترقية VB.NET مع برنامج يحتوي على صفيف تحكم. الرمز قبيح مرة أخرى ، لكنه يعمل. الأخبار السيئة هي أن Microsoft لن تضمن استمرار دعم مكونات التوافق ، وليس من المفترض أن تستخدمها.

رمز VB.NET لإنشاء واستخدام "صفائف التحكم" أطول بكثير وأكثر تعقيدًا.

ووفقًا لما ذكرته Microsoft ، فإن القيام بشيء ما بالقرب من ما يمكنك القيام به في VB 6 يتطلب إنشاء "مكون بسيط يكرر وظائف صفيف التحكم".

تحتاج إلى فئة جديدة ونموذج استضافة لتوضيح ذلك. يخلق الفصل فعليًا ملصقات جديدة ويدمرها. رمز الفصل الكامل هو كما يلي:

فئة الجمهور LabelArray
يرث System.Collections.CollectionBase
الخاص ReadOnly HostForm باسم _
System.Windows.Forms.Form
الوظيفة العامة AddNewLabel () _
كما System.Windows.Forms.Label
إنشاء مثيل جديد لفئة التسمية.
قاتمة aababel كما System.Windows.Forms.Label الجديد
أضف الملصق إلى المجموعة
القائمة الداخلية.
Me.List.Add (aLabel)
أضف الملصق إلى مجموعة الضوابط
'من النموذج المشار إليه بواسطة حقل HostForm.
HostForm.Controls.Add (aLabel)
قم بتعيين خصائص intial لكائن التسمية.
aLabel.Top = العدد * 25
aLabel.Width = 50
aLabel.Left = 140
aLabel.Tag = Me.Count
aLabel.Text = "Label" & Me.Count.ToString
عودة aababel
وظيفة النهاية
عام فرعي جديد (_
مضيف ByVal باسم System.Windows.Forms.Form)
HostForm = المضيف
Me.AddNewLabel ()
نهاية الفرعية
خاصية ReadOnly العامة الافتراضية _
عنصر (مؤشر ByVal كـ عدد صحيح) كـ _
System.Windows.Forms.Label
احصل على
إرجاع CType (Me.List.Item (الفهرس) ، _
System.Windows.Forms.Label)
نهاية الحصول على
نهاية الملكية
إزالة العامة الفرعية ()
تحقق للتأكد من وجود علامة للإزالة.
إذا Me.Count> 0 ثم
قم بإزالة التسمية الأخيرة المضافة إلى الصفيف
'من مجموعة عناصر تحكم النموذج المضيف.
لاحظ استخدام الخاصية الافتراضية في
'الوصول إلى مجموعة.
HostForm.Controls.Remove (Me (Me.Count - 1))
Me.List.RemoveAt (Me.Count - 1)
إنهاء إذا
نهاية الفرعية
نهاية الدرجة

لتوضيح كيفية استخدام رمز الفئة هذا ، يمكنك إنشاء نموذج يستدعي. يجب عليك استخدام الكود الموضح أدناه في النموذج:

Form1 الفئة العامة يرث System.Windows.Forms.Form #Region "رمز إنشاء مصمم Windows" "يجب عليك أيضًا إضافة العبارة: 'MyControlArray = New LabelArray (Me)' بعد استدعاء InitializeComponent () في رمز المنطقة المخفية. قم بتعريف كائن ButtonArray جديد. Dim MyControlArray As LabelArray Private Sub btnLabelAdd_Click (_ مرسل ByVal باسم System.Object ، _ ByVal e As System.EventArgs) _ Handles btnLabelAdd.Click 'Call the AddNewLabel method of MyControlArray. MyControlArray.AddNewLabel () 'تغيير خاصية BackColor' من الزر 0. MyControlArray (0) .BackColor = _ System.Drawing.Color.Red End Sub Private Sub btnLabelRemove_Click (_ مرسل ByVal باسم System.Object ، _ ByVal e As System) .EventArgs) _ مقابض btnLabelRemove.Click 'استدعاء طريقة إزالة MyControlArray. MyControlArray.Remove () نهاية فئة نهاية الفرعية

أولاً ، هذا لا يؤدي المهمة حتى في Design Time مثلما اعتدنا على القيام بذلك في VB 6! وثانياً ، ليسوا في صفيف ، فهم في مجموعة VB.NET - شيء مختلف كثيرًا عن الصفيف.

السبب في أن VB.NET لا يدعم VB 6 "صفيف التحكم" هو أنه لا يوجد شيء مثل صفيف "التحكم" (لاحظ تغيير علامات الاقتباس). ينشئ VB 6 مجموعة من وراء الكواليس ويجعلها تظهر كصفيف للمطور. ولكنها ليست مجموعة ولديك سيطرة قليلة عليها خارج الوظائف المتوفرة من خلال IDE.

VB.NET ، من ناحية أخرى ، يطلق عليه ما هو عليه: مجموعة من الكائنات. ويقومون بتسليم المفاتيح للمملكة للمطور عن طريق إنشاء الأمر برمته في العلن.

كمثال على نوع المزايا التي يعطيها للمطور ، في VB 6 ، يجب أن تكون عناصر التحكم من نفس النوع ، وكان يجب أن يكون لها نفس الاسم. نظرًا لأن هذه مجرد كائنات في VB.NET ، يمكنك جعلها أنواعًا مختلفة ومنحها أسماء مختلفة وتظل تديرها في نفس مجموعة الكائنات.

في هذا المثال ، يعالج حدث Click نفسه زرين ومربع اختيار ويعرض أي زر تم النقر عليه. القيام بذلك في سطر واحد من التعليمات البرمجية مع VB 6!

Sub Sub MixedControls_Click (_
ByVal المرسل باسم System.Object ، _
ByVal e As System.EventArgs) _
يعالج Button1.Click ، ​​_
Button2.Click ، ​​_
CheckBox1.Click
يجب أن يكون البيان أدناه عبارة واحدة طويلة!
"إنها على أربعة أسطر هنا لإبقائها ضيقة
يكفي لتناسب صفحة الويب
Label2.Text =
Microsoft.VisualBasic.Right (sender.GetType.ToString،
Len (sender.GetType.ToString) -
(InStr (sender.GetType.ToString، "Forms") + 5))
نهاية الفرعية

إن حساب السلسلة الفرعية هو نوع من التعقيد ، لكنه ليس ما نتحدث عنه هنا. يمكنك فعل أي شيء في حدث Click. يمكنك ، على سبيل المثال ، استخدام نوع عنصر التحكم في عبارة If للقيام بأشياء مختلفة لعناصر تحكم مختلفة.

ملاحظات فرانك حول دراسات الحوسبة على المصفوفات

قدمت مجموعة دراسة فرانك مثالاً على نموذج يحتوي على 4 ملصقات وزرين. الزر 1 يمسح التسميات ويملأها الزر 2. إنها فكرة جيدة أن تقرأ سؤال فرانك الأصلي مرة أخرى ولاحظ أن المثال الذي استخدمه كان حلقة يتم استخدامها لمسح خاصية Caption لمجموعة من مكونات Label. فيما يلي VB.NET المكافئ لرمز VB 6. هذا الرمز يفعل ما طلب فرانك أصلاً!

Form1 الفئة العامة يرث System.Windows.Forms.Form #Region "Windows Form Designer إنشاء التعليمات البرمجية" Dim LabelArray (4) باسم Label "تعلن عن مجموعة من التسميات Private Sub1 Form1_Load (_ ByVal مرسل باسم System.Object ، _ ByVal e As System .EventArgs) _ Handles MyBase.Load SetControlArray () End Sub Sub SetControlArray () LabelArray (1) = Label1 LabelArray (2) = Label2 LabelArray (3) = Label3 LabelArray (4) = Label4 End Sub Sub Button1_Click باسم System.Object ، _ ByVal e As System.EventArgs) _ Handles Button1.Click 'Button 1 مسح صفيف Dim a As Integer للحصول على = 1 إلى 4 LabelArray (a) .Text = "" التالي End Sub Sub Sub Button2_Click (_ مرسل ByVal باسم System.Object ، _ ByVal e As System.EventArgs) _ Handles Button2.Click 'Button 2 Fill Array Dim a As Integer For = 1 إلى 4 LabelArray (a) .Text = _ "Control Array" & CStr ( أ) نهاية نهاية الدرجة الفرعية النهاية

إذا جربت هذا الرمز ، فستكتشف أنه بالإضافة إلى إعداد خصائص الملصقات ، يمكنك أيضًا استدعاء الأساليب. فلماذا ذهبت أنا (و Microsoft) إلى مشكلة لإنشاء رمز "القبيح" في الجزء الأول من المقالة؟

لا بد لي من عدم الموافقة على أنها "صفيف تحكم" بالفعل بالمعنى التقليدي للـ VB. VB 6 Control Array هو جزء معتمد من بناء جملة VB 6 ، وليس مجرد تقنية. في الواقع ، ربما تكون الطريقة لوصف هذا المثال أنه مجموعة من عناصر التحكم ، وليس صفيف تحكم.

في الجزء الأول ، اشتكت من أن مثال Microsoft يعمل فقط في وقت التشغيل وليس وقت التصميم. يمكنك إضافة عناصر تحكم من نموذج وحذفها بشكل حيوي ، لكن يجب تنفيذ الأمر برمته في التعليمات البرمجية. لا يمكنك سحب وإسقاط عناصر التحكم لإنشاءها كما يمكنك في VB 6. هذا المثال يعمل بشكل رئيسي في وقت التصميم وليس في وقت التشغيل. لا يمكنك إضافة وحذف عناصر التحكم ديناميكيًا في وقت التشغيل. بطريقة ما ، هو عكس المثال الأول في الجزء الأول.

مثال صفيف التحكم VB 6 الكلاسيكية هو نفسه الذي يتم تنفيذه في التعليمات البرمجية .NET VB. هنا في VB 6 code (هذا مأخوذ من Mezick & Hillier ، دليل اختبار شهادة Visual Basic 6، ص 206 - تم تعديله قليلاً ، حيث أن المثال في الكتاب ينتج عنه عناصر تحكم لا يمكن رؤيتها):

تعتيم MyTextBox كـ VB.TextBox intNumber ثابت كـ عدد صحيح intNumber = intNumber + 1 تعيين MyTextBox = _ Me.Controls.Add ("VB.TextBox"، _ "Text" & intNumber) MyTextBox.Text = MyTextBox.Name MyTextBox.Visible = صحيح MyTextBox.Left = _ (intNumber - 1) * 1200

ولكن كما أتفق مع Microsoft (وأنا) ، فإن صفيف التحكم VB 6 غير ممكن في VB.NET. لذلك أفضل ما يمكنك فعله هو تكرار الوظيفة. تكرر مقالي الوظيفة الموجودة في المثال Mezick & Hillier. يكرر رمز Study Group وظيفة القدرة على ضبط الخصائص وطرق الاتصال.

وبالتالي فإن الخلاصة هي أنه يعتمد حقًا على ما تريد القيام به. لا يحتوي VB.NET على كل شيء مكتوب كجزء من اللغة - حتى الآن - لكنه في النهاية أكثر مرونة.

جون Fannon تأخذ على صفائف التحكم

كتب جون: كنت بحاجة إلى صفائف تحكم لأنني أردت وضع جدول بسيط للأرقام في نموذج وقت التشغيل. لم أكن أريد الغثيان من وضع كل منهم على حدة وأردت استخدام VB.NET. تقدم Microsoft حلاً مفصلاً لمشكلة بسيطة ، ولكنها مطرقة ثقيلة كبيرة جدًا لتكسير صمولة صغيرة جدًا. بعد بعض التجارب ، وصلت في النهاية إلى حل. إليك كيف فعلت ذلك.

يوضح المثال حول Visual Basic أعلاه كيف يمكنك إنشاء مربع نص في نموذج عن طريق إنشاء مثيل للكائن ، وإعداد الخصائص ، وإضافته إلى مجموعة عناصر التحكم التي تعد جزءًا من كائن النموذج.

خافت txtDataShow جديد TextBox
txtDataShow.Height = 19
txtDataShow.Width = 80
txtDataShow.Location = نقطة جديدة (X ، Y)
Me.Controls.Add (txtDataShow)
على الرغم من أن حل Microsoft يُنشئ فئة ، إلا أنني اعتقدت أنه سيكون من الممكن التفاف كل هذا في روتين فرعي بدلاً من ذلك. في كل مرة تقوم فيها بالاتصال بهذا الروتين الفرعي ، تقوم بإنشاء مثيل جديد لمربع النص في النموذج. إليك الكود الكامل:

الدرجة العامة Form1
يرث System.Windows.Forms.Form

#Region "Windows Form Designer إنشاء رمز"

Sub BtnStart_Click (_)
ByVal المرسل باسم System.Object ، _
ByVal e As System.EventArgs) _
مقابض btnStart.Click

خافت أنا كعدد صحيح
خافت sData كسلسلة
لأني = 1 إلى 5
sData = CStr (I)
استدعاء AddDataShow (sData ، I)
التالى
نهاية الفرعية
Sub AddDataShow (_
ByVal sText As String، _
ByVal I As Integer)

خافت txtDataShow جديد TextBox
قاتمة UserLft ، UserTop كعدد صحيح
خافت س ، ص كعدد صحيح
UserLft = 20
UserTop = 20
txtDataShow.Height = 19
txtDataShow.Width = 25
txtDataShow.TextAlign = _
HorizontalAlignment.Center
txtDataShow.BorderStyle = _
BorderStyle.FixedSingle
txtDataShow.Text = sText
X = UserLft
Y = UserTop + (I - 1) * txtDataShow.Height
txtDataShow.Location = نقطة جديدة (X ، Y)
Me.Controls.Add (txtDataShow)
نهاية الفرعية
نهاية الدرجة
نقطة جيدة جدا ، جون. هذا بالتأكيد أبسط بكثير من رمز Microsoft ... لذلك أتساءل لماذا أصروا على القيام بذلك بهذه الطريقة؟

لبدء تحقيقنا ، دعونا نحاول تغيير أحد تخصيصات الممتلكات في الكود. لنغير

txtDataShow.Height = 19
إلى

txtDataShow.Height = 100
فقط للتأكد من وجود فرق ملحوظ.

عندما نقوم بتشغيل الكود مرة أخرى ، نحصل على ... Whaaaat ؟؟؟ ... نفس الشيء. لا تغيير على الإطلاق. في الواقع ، يمكنك عرض القيمة باستخدام عبارة مثل MsgBox (txtDataShow.Height) وستظل تحصل على 20 كقيمة للخاصية بغض النظر عن ما تقوم بتعيينه لها. لماذا يحدث هذا؟

الجواب هو أننا لا نستمد فصلنا الخاص لإنشاء الكائنات ، بل نضيف أشياء إلى فصل آخر ، لذلك يتعين علينا اتباع قواعد الفصل الآخر. وتذكر تلك القواعد أنه لا يمكنك تغيير خاصية الارتفاع. (Wellllll ... يمكنك. إذا قمت بتغيير الخاصية Multiline إلى True ، فيمكنك تغيير الارتفاع.)

لماذا يمضي VB.NET قدما وينفذ الكود دون حتى تذمر أنه قد يكون هناك شيء خاطئ ، في الواقع ، يتجاهل تماما البيان الخاص بك هو "قبضة أخطر". قد أقترح على الأقل تحذير في الترجمة ، ولكن. (تلميح! تلميح! تلميح! هل تستمع Microsoft؟)

المثال من الجزء الأول يرث من فئة أخرى ، وهذا يجعل الخصائص متاحة للرمز في الفئة الوراثية. تغيير خاصية الارتفاع إلى 100 في هذا المثال يعطينا النتائج المتوقعة. (مرة أخرى ... إخلاء مسؤولية واحد: عند إنشاء مثيل جديد لمكون Label كبير ، فإنه يغطى العنصر القديم. لرؤية مكونات Label الجديدة بالفعل ، يجب عليك إضافة الأسلوب استدعاء aLabel.BringToFront ().)

يوضح هذا المثال البسيط أنه على الرغم من أنه يمكننا ببساطة إضافة كائنات إلى فصل آخر (وأحيانًا يكون هذا هو الشيء الصحيح الذي يجب القيام به) ، فإن برمجة التحكم في الكائنات تتطلب استنباطها في فصل دراسي وبالطريقة الأكثر تنظيماً (أجرؤ على القول ، "طريقة .NET" هي إنشاء خصائص وأساليب في الفئة المشتقة الجديدة لتغيير الأشياء. بقي جون غير مقتنع في البداية. وقال إن نهجه الجديد يناسب غرضه على الرغم من وجود قيود من عدم كونه "COO" (كائن صحيح المنحى). في الآونة الأخيرة ، كتب جون ،

"... بعد كتابة مجموعة من 5 مربعات نصية في وقت التشغيل ، أردت تحديث البيانات في جزء لاحق من البرنامج - لكن لم يتغير شيء - كانت البيانات الأصلية لا تزال موجودة.

لقد وجدت أنه يمكنني حل المشكلة عن طريق كتابة الكود لأخلع الصناديق القديمة وإعادتها مرة أخرى ببيانات جديدة. أفضل طريقة للقيام بذلك هي استخدام Me.Refresh. لكن هذه المشكلة لفتت انتباهي إلى الحاجة إلى توفير طريقة لطرح مربعات النص بالإضافة إلى إضافتها ".

استخدم رمز John متغيرًا عموميًا لتتبع عدد عناصر التحكم التي تمت إضافتها إلى النموذج بحيث تكون طريقة ...

نموذج فرعي خاص 1 تحميل (_
ByVal المرسل باسم System.Object ، _
ByVal e As System.EventArgs) _
يعالج MyBase.Load
CntlCnt0 = Me.Controls.Count
نهاية الفرعية

ثم يمكن إزالة عنصر التحكم "الأخير" ...

N = Me.Controls.Count - 1
Me.Controls.RemoveAt (N)
أشار جون إلى أنه "ربما يكون هذا خرقاء بعض الشيء".

إنها الطريقة التي تتبعها Microsoft لتعقب الكائنات في COM AND في رمز المثال "القبيح" أعلاه.

لقد عدت الآن إلى مشكلة إنشاء عناصر تحكم ديناميكية على نموذج في وقت التشغيل ، ولقد كنت أبحث مرة أخرى في مقالات "ما حدث للتحكم في المصفوفات".

لقد قمت بإنشاء الفئات ويمكنني الآن وضع عناصر التحكم في النموذج بالطريقة التي أريدها أن تكون.

أوضح جون كيفية التحكم في موضع عناصر التحكم في مربع المجموعة باستخدام الفئات الجديدة التي بدأ استخدامها. ربما كانت مايكروسوفت لديها الحق في حلها "القبيح" بعد كل شيء!