השמטת מערכי בקרה מ- VB.NET מהווה אתגר למי שמלמד על מערכים.
- כבר לא ניתן פשוט להעתיק פקד, כגון תיבת טקסט, ואז להדביק אותה (פעם או כמה פעמים) כדי ליצור מערך שליטה.
- קוד VB.NET ליצירת מבנה הדומה למערך בקרה היה, בכל הספרים ב- VB.NET שקניתי ובאופן מקוון, הרבה יותר זמן ומורכב הרבה יותר. הוא חסר את הפשטות בקידוד מערך בקרה שנמצא ב- VB6.
אם אתה מתייחס לספריית התאימות VB6, ישנם שם חפצים הפועלים די כמו מערכי בקרה. כדי לראות למה אני מתכוון, פשוט השתמש באשף השדרוג VB.NET עם תוכנית המכילה מערך בקרה. הקוד שוב מכוער, אך הוא עובד. החדשות הרעות הן שמיקרוסופט לא תבטיח כי רכיבי התאימות ימשיכו להיות נתמכים, ואתה לא אמור להשתמש בהם.
קוד VB.NET ליצירת "מערכי בקרה" ושימוש בו הוא הרבה יותר ארוך ומורכב הרבה יותר.
לדברי מיקרוסופט, כדי לעשות משהו אפילו קרוב למה שאתה יכול לעשות ב- VB 6, נדרש ליצור "רכיב פשוט המשכפל את פונקציונליות מערך השליטה."
כדי להמחיש זאת אתה זקוק לשיעור חדש וגם לטופס אירוח. הכיתה למעשה יוצרת והורס תוויות חדשות. קוד הכיתה השלם הוא כדלקמן:
LabelArray בכיתה ציבורית
מערכת ירושות. אוספים. CollectionBase
קריאה פרטית בלבד HostForm As _
מערכת. חלונות. טפסים. טופס
פונקציה ציבורית AddNewLabel () _
כמערכת. חלונות. טפסים. תווית
'צור מופע חדש משיעור התווית.
עמעום תווית כמערכת חדשה. חלונות. טפסים. תווית
'הוסף את התווית לסרטים של האוסף
רשימה פנימית.
אני. רשימה. הוסף (תווית)
'הוסף את התווית לאוסף הבקרות
'של הטופס אליו מופנה שדה HostForm.
HostForm. בקרות. הוסף (תווית)
'הגדר תכונות אינטיאליות עבור אובייקט התווית.
תווית. למעלה = ספירה * 25
תווית. רוחב = 50
תווית. שמאל = 140
תווית. תג = אני. לספור
תווית. טקסט = "תווית" & לי. לספור. ToString
החזר את התווית
פונקצית סיום
תת ציבורי חדש (_
ByVal מארח כמערכת. חלונות. טפסים. טופס)
HostForm = מארח
אני. AddNewLabel ()
סיום משנה
נכס ברירת מחדל לקריאה ציבורית בלבד _
פריט (מדד ByVal כמספר שלם) כ _
מערכת. חלונות. טפסים. תווית
לקבל
החזר CType (רשימת רשימת Me. פריט (אינדקס), _
מערכת. חלונות. טפסים. תווית)
סוף גט
נכס קצה
תת ציבורי הסר ()
'בדוק כדי להיות בטוח שיש תווית להסרה.
אם אני. ספירה> 0 ואז
'הסר את התווית האחרונה שנוספה למערך
'מאוסף השולטת בטופס המארח.
'שימו לב לשימוש במאפיין ברירת המחדל ב-
גישה למערך.
HostForm. בקרות. הסר (אני (אני. ספירה - 1))
אני. רשימה. RemoveAt (אני. ספירה - 1)
סוף אם
סיום משנה
סיום כיתה
כדי להמחיש כיצד יש להשתמש בכיתה בכיתה זו, תוכלו ליצור טופס המכנה אותו. יהיה עליכם להשתמש בקוד המוצג להלן בטופס:
טופס מחלקה ציבורית 1. מערכת ירושות. חלונות. טפסים. טופס. #Region "קוד שנוצר מעצבי טפסים של Windows" 'גם עליך להוסיף את ההצהרה:' MyControlArray = LabelArray חדש (אני) לאחר קריאת ה- InitializeComponent (). קוד אזור מוסתר. 'הכרז על אובייקט ButtonArray חדש. אפלולי את MyControlArray כ- LabelArray. Sub פרטי btnLabelAdd_Click (_. שולח ByVal כמערכת. חפץ, _. מערכת ByVal e As. EventArgs) _. מטפל btnLabelAdd. לחץ על. 'התקשר לשיטת AddNewLabel. 'של MyControlArray. MyControlArray. AddNewLabel () 'שנה את המאפיין BackColor. 'של הכפתור 0. MyControlArray (0). BackColor = _. מערכת. ציור. צבע. אדום. סיום משנה תת פרטי btnLabel הסר_קליק (_. שולח ByVal כמערכת. חפץ, _. מערכת ByVal e As. EventArgs) _. מטפל btnLabel Remover. לחץ על. התקשר לשיטת הסר של MyControlArray. MyControlArray. הסר () סיום משנה סיום כיתה
ראשית, זה אפילו לא עושה את העבודה ב- Design Time כמו שנהגנו לעשות זאת ב- VB 6! ושנית, הם לא נמצאים במערך, הם באוסף VB.NET - דבר שונה בהרבה ממערך.
הסיבה VB.NET אינה תומכת במערך הבקרה של VB 6 היא שאין דבר כזה מערך "שליטה" "(שימו לב לשינוי במרכאות). VB 6 יוצר אוסף מאחורי הקלעים וגורם לו להופיע כמערך למפתח. אבל זה לא מערך ויש לך שליטה מועטה עליו מעבר לפונקציות המסופקות באמצעות ה- IDE.
לעומת זאת, VB.NET קורא לזה מה שהוא: אוסף של חפצים. והם מוסרים למפתח את מפתחות הממלכה על ידי יצירת הדבר כולו בשטח פתוח.
כדוגמה לסוג היתרונות שזה נותן למפתח, ב- VB 6 הפקדים היו צריכים להיות מאותו סוג, והם היו צריכים להיות בעלי אותו שם. מכיוון שאלו רק אובייקטים ב- VB.NET, אתה יכול להפוך אותם לסוגים שונים ולתת להם שמות שונים ועדיין לנהל אותם באותה אוסף של אובייקטים.
בדוגמה זו, אותו אירוע קליק מטפל בשני כפתורים ותיבת סימון ומציג על איזה לחיצה. עשה זאת בשורת קוד אחת עם VB 6!
תת פרטי מעורב בקרות_קליק (_
שולח ByVal כמערכת. חפץ, _
מערכת ByVal e As. EventArgs) _
לחצן ידיות1.לחץ, _
לחצן 2. לחץ, _
CheckBox1. לחץ
'ההצהרה שלהלן צריכה להיות הצהרה ארוכה אחת!
'זה על ארבע שורות כאן כדי לשמור על צרה
מספיק כדי להתאים לדף אינטרנט
Label2.Text =
מיקרוסופט. ויז'ואל בייסיק. מימין (שולח. GetType. ToString,
לן (שולח. GetType. ToString) -
(InStr (שולח. GetType. ToString, "טפסים") + 5))
סיום משנה
חישוב המחרוזת הוא די מורכב, אבל לא באמת על מה מדובר כאן. אתה יכול לעשות הכל באירוע הקליק. אתה יכול, למשל, להשתמש בסוג הפקד בהצהרת If כדי לעשות דברים שונים לבקרות שונות.
משוב קבוצת לימודי המחשוב של פרנק על מערכים
קבוצת המחקר של פרנק סיפקה דוגמה עם טופס הכולל 4 תוויות ושני כפתורים. כפתור 1 מנקה את התוויות וכפתור 2 ממלא אותן. כדאי לקרוא שוב את השאלה המקורית של פרנק ולשים לב שהדוגמה בה השתמש היה לולאה המשמשת לניקוי המאפיין הכיתוב של מערך של רכיבי Label. להלן המקבילה VB.NET לאותו קוד VB 6. קוד זה עושה את מה שפרנק ביקש במקור!
טופס מחלקה ציבורית 1. מערכת ירושות. חלונות. טפסים. טופס. #Region "קוד שנוצר מעצבי טפסים של Windows" Dim LabelArray (4) כתווית. להכריז על מגוון תוויות. טופס משנה פרטי 1_Load (_. שולח ByVal כמערכת. חפץ, _. מערכת ByVal e As. EventArgs) _. מטפל ב- MyBase. עומס. SetControlArray () סיום משנה Sub SetControlArray () LabelArray (1) = Label1. LabelArray (2) = Label2. LabelArray (3) = Label3. LabelArray (4) = Label4. סיום משנה לחצן משנה פרטי 1_לחץ (_. שולח ByVal כמערכת. חפץ, _. מערכת ByVal e As. EventArgs) _. כפתור ידיות. לחץ על. כפתור 1 מערך נקה. עמעום כמספר שלם. עבור a = 1 עד 4. LabelArray (א). טקסט = "" הבא. סיום משנה לחצן משנה פרטי 2_קליק (_. שולח ByVal כמערכת. חפץ, _. מערכת ByVal e As. EventArgs) _. כפתור ידיות 2. לחץ. כפתור 2 מילוי מערך. עמעום כמספר שלם. עבור a = 1 עד 4. LabelArray (א). טקסט = _. מערך בקרה ו- CStr (א) הבא. סיום משנה סיום כיתה
אם תתנסו בקוד זה, תגלו שבנוסף להגדרת מאפייני התוויות, תוכלו גם לקרוא לשיטות. אז מדוע אני (ומיקרוסופט) עברתי לכל הבעיות לבנות את הקוד "המכוער" בחלק הראשון של המאמר?
אני צריך לא להסכים שזה באמת "מערך שליטה" במובן VB הקלאסי. מערך הבקרה VB 6 הוא חלק נתמך בתחביר VB 6, ולא רק טכניקה. למעשה, אולי הדרך לתאר את הדוגמא הזו היא שמדובר במערך בקרות ולא במערך בקרה.
בחלק הראשון התלוננתי שהדוגמה של מיקרוסופט עבדה רק בזמן ריצה ולא בזמן עיצוב. אתה יכול להוסיף ולמחוק פקדים מטופס באופן דינמי, אבל כל העניין צריך להיות מיושם בקוד. אינך יכול לגרור ולשחרר פקדים כדי ליצור אותם כמו שאתה יכול ב- VB 6. דוגמא זו עובדת בעיקר בזמן העיצוב ולא בזמן הריצה. אינך יכול להוסיף ולמחוק פקדים באופן דינמי בזמן ריצה. במובן מסוים, זה ההפך הגמור מדוגמת החלק הראשון.
הדוגמה של מערך הבקרה הקלאסי של VB 6 היא זהה המיושמת בקוד ה- VB .NET. כאן בקוד VB 6 (זה לקוח מ- Mezick & Hillier, מדריך לבחינות הסמכה של Visual Basic 6, עמ '206 - שונה מעט, מכיוון שהדוגמה בספר מביאה לבקרות שלא ניתן לראות):
טשטש את MyTextBox כ- VB.TextBox. מספר מספר סטטי כמספר שלם. intNumber = intNumber + 1. הגדר את MyTextBox = _. אני. בקרות. הוסף ("VB.TextBox", _. "טקסט" ומספר intNumber) MyTextBox. טקסט = MyTextBox. שם. MyTextBox. גלוי = נכון. MyTextBox. שמאל = _. (intNumber - 1) * 1200
אך כפי שמיקרוסופט (ואני) מסכימים, מערכי בקרה של VB 6 אינם אפשריים ב- VB.NET. אז הכי טוב שתוכלו לעשות הוא לשכפל את הפונקציונליות. המאמר שלי שכפל את הפונקציונליות שנמצאה בדוגמה Mezick & Hillier. קוד קבוצת המחקר משכפל את הפונקציונליות של היכולת להגדיר מאפיינים ושיטות שיחה.
אז בשורה התחתונה זה באמת תלוי במה שאתה רוצה לעשות. ל- VB.NET אין כל העניין עטוף כחלק מהשפה - ובכל זאת - אך בסופו של דבר זה הרבה יותר גמיש.
מערכי השליטה של ג'ון פאנון
ג'ון כתב: הייתי זקוק למערכי בקרה כי רציתי לשים טבלה פשוטה של מספרים על טופס בזמן ריצה. לא רציתי את הבחילה של להציב את כולם בנפרד ורציתי להשתמש ב- VB.NET. מיקרוסופט מציעה פיתרון מאוד מפורט לבעיה פשוטה, אך זהו מזחלת גדולה מאוד לפיצוח אגוז קטן מאוד. אחרי כמה ניסויים, בסופו של דבר נתקלתי בפתרון. הנה איך עשיתי זאת.
הדוגמה אודות Visual Basic שלמעלה מראה כיצד ניתן ליצור TextBox בטופס על ידי יצירת מופע של האובייקט, הגדרת מאפיינים והוספתו לאוסף פקדים המהווה חלק מהטופס חפץ.
Dim txtData Show As TextBox חדש
txtDataShow. גובה = 19
txtDataShow. רוחב = 80
txtDataShow. מיקום = נקודה חדשה (X, Y)
אני. בקרות. הוסף (txtDataShow)
למרות שהפתרון של מיקרוסופט מייצר Class, נימקתי שאפשר לעטוף את כל זה בתת-רחוב במקום זאת. בכל פעם שאתה מתקשר לתכנית המשנה הזו אתה יוצר מופע חדש של תיבת הטקסט בטופס. להלן הקוד המלא:
טופס מחלקה ציבורית 1
מערכת ירושות. חלונות. טפסים. טופס
#Region "קוד שנוצר מעצבי טפסים של Windows"
תת פרטי BtnStart_Click (_
שולח ByVal כמערכת. חפץ, _
מערכת ByVal e As. EventArgs) _
מטפל btnStart. לחץ על
עמום אני כמספר שלם
Dim sData כמחרוזת
עבור אני = 1 עד 5
sData = CStr (I)
התקשר אל AddDataShow (sData, I)
הבא
סיום משנה
Sub AddDataShow (_
ByVal sText כמחרוזת, _
ByVal I כמספר שלם)
Dim txtData Show As TextBox חדש
עומק UserLft, UserTop כמספר שלם
עומק X, Y כמספר שלם
UserLft = 20
UserTop = 20
txtDataShow. גובה = 19
txtDataShow. רוחב = 25
txtDataShow. TextAlign = _
יישור אופקי. מרכז
txtDataShow. BorderStyle = _
BorderStyle. FixedSingle
txtDataShow. טקסט = sText
X = UserLft
Y = UserTop + (I - 1) * txtDataShow. גובה
txtDataShow. מיקום = נקודה חדשה (X, Y)
אני. בקרות. הוסף (txtDataShow)
סיום משנה
סיום כיתה
נקודה טובה מאוד, ג'ון. זה בהחלט הרבה יותר פשוט מהקוד של מיקרוסופט... אז אני תוהה מדוע הם התעקשו לעשות את זה ככה?
כדי להתחיל בחקירה שלנו, בוא ננסה לשנות אחת מהקצאות הנכס בקוד. בוא נשנה
txtDataShow. גובה = 19
ל
txtDataShow. גובה = 100
רק כדי לוודא שיש הבדל בולט.
כשאנחנו מפעילים את הקוד שוב אנו מקבלים... ווהאאת??? ... אותו הדבר. אין שינוי כלל. למעשה, אתה יכול להציג את הערך עם משפט כמו MsgBox (txtDataShow. גובה) ואתה עדיין מקבל 20 כערך הנכס לא משנה מה אתה מקצה לו. מדוע זה קורה?
התשובה היא שאנחנו לא שואבים את הכיתה שלנו כדי ליצור את האובייקטים, אנחנו רק מוסיפים דברים לכיתה אחרת אז עלינו לפעול לפי הכללים של הכיתה האחרת. וכללים אלה קובעים כי אינך יכול לשנות את נכס הגובה. (טוב... אתה יכול. אם תשנה את המאפיין Multiline ל- True, תוכל לשנות את הגובה.)
מדוע VB.NET ממשיך ומבצע את הקוד מבלי אפילו לייבב שאולי יש משהו לא בסדר כאשר, למעשה, זה מתעלם לחלוטין מההצהרה שלך היא תפיסה שלמה. עם זאת, אני עשוי להציע לפחות אזהרה בקומפליקט. (רמז! רמז! רמז! האם מיקרוסופט מקשיבה?)
הדוגמא מחלק I יורשת מכיתה אחרת, וזה הופך את המאפיינים לזמינים לקוד במחלקה הירושה. שינוי נכס הגובה ל 100 בדוגמה זו נותן לנו את התוצאות הצפויות. (שוב... הצהרת אחריות אחת: כאשר נוצר מופע חדש של רכיב Label גדול, הוא מכסה את הישן. כדי לראות בפועל את רכיבי הלייבל החדשים, עליך להוסיף את שיחת השיטה aLabel. BringToFront ().)
הדוגמה הפשוטה הזו מראה שלמרות שאנו פשוט יכולים להוסיף אובייקטים למחלקה אחרת (ולפעמים זה הדבר הנכון לעשות), תכנות שליטה על האובייקטים דורש שנגזור אותם בכיתה והדרך המאורגנת ביותר (אני מעז לומר, "דרך NET." ??) היא ליצור מאפיינים ושיטות בכיתה הנגזרת החדשה לשינוי דברים. ג'ון נותר לא משוכנע בהתחלה. לדבריו, הגישה החדשה שלו מתאימה למטרתו למרות שיש מגבלות מלהיות לא "COO" (נכון לכיוון אובייקט). אולם לאחרונה, ג'ון כתב,
"... לאחר שכתבתי קבוצה של 5 תיבות טקסט בזמן ריצה, רציתי לעדכן את הנתונים בחלק שלאחר מכן של התוכנית - אך שום דבר לא השתנה - הנתונים המקוריים עדיין היו שם.
גיליתי שאני יכול לעקוף את הבעיה על ידי כתיבת קוד כדי להוריד את התיבות הישנות ולהחזיר אותם שוב עם נתונים חדשים. דרך טובה יותר לעשות זאת תהיה להשתמש בי. רענן. אבל בעיה זו הסבה את תשומת ליבי לצורך בהספקה של שיטה לחיסור תיבות הטקסט והוספתן. "
הקוד של ג'ון השתמש במשתנה גלובלי כדי לעקוב אחר מספר הפקדים שנוספו לטופס כך ששיטה ...
טופס משנה פרטי 1_Load (_
שולח ByVal כמערכת. חפץ, _
מערכת ByVal e As. EventArgs) _
מטפל ב- MyBase. עומס
CntlCnt0 = אני. בקרות. לספור
סיום משנה
ואז ניתן היה להסיר את הפקד "האחרון" ...
N = אני. בקרות. ספירה - 1
אני. בקרות. RemoveAt (N)
ג'ון ציין כי "אולי זה קצת מגושם."
זו הדרך בה מיקרוסופט עוקבת אחר אובייקטים ב- COM AND בקוד הדוגמא "המכוער" שלהם למעלה.
חזרתי עכשיו לבעיה של יצירת בקרות באופן דינמי על טופס בזמן ריצה, ובחנתי שוב את המאמרים 'מה קרה למערכי בקרה'.
יצרתי את השיעורים וכעת אוכל להציב את הפקדים על הטופס באופן שאני רוצה שיהיו.
ג'ון הדגים כיצד לשלוט על מיקום הבקרות בתיבה קבוצתית באמצעות המחלקות החדשות בהן החל להשתמש. אולי למיקרוסופט זה היה נכון בפתרון "המכוער" שלהם!