תעלומה ב VB.NET - שגרת אירוע שרצה על דעת עצמה...
-
בס"ד
שלום וברכה לכל החברים היקרים!
אקדים ואומר, שאלתי היא רק לצורך ההבנה העקרונית - איך זה קורה. איך "לעקוף" בקלות את "הבעייה" אני יודע לבד.ובכן:
אני כותב תוכנה קטנה לאשתי (הקלדנית) שתעזור לה לחשב את הסכום לגבייה, מלקוחות שמביאים הרבה קבצים קטנטנים.
התוכנה מבקשת לבחור קבצי Word, מפעילה עליהם ספירת תווים אוטומטית (באמצעות Microsoft.Office.Interop.Word),
ומחשבת את הסכום לתשלום לפי כמה קריטריונים: סכום בסיס לאלף תוים, סכום שונה לעבודה בדחיפות מיידית, ועוד.לכל קריטריון הקציתי TextBox שבו אשתי מכניסה את הסכום הרצוי (כמובן שכברירת מחדל יש שם כבר את הסכומים הרגילים שלה),
והמחשב מכפיל את התווים לפי הסכומים שמופיעים בטקסט בוקסים ומוציא תוצאה לתשלום.
הסיבה שבחרתי ב TextBox ולא ב NumericUpDown, זה לאפשר לה לעבוד בסכומים עם שברים (לדוגמא, 3.5 ש"ח).כמובן שכמו מתכנת "שרוצה להיות גדול", דאגתי לסגור פינות, עם שגרה בשם KeyPressed שתטפל באירועי הזנת טקסט בטקסטבוקסים,
ובודקת באמצעות Regex האם הוזנה ספרה, נקודה, או שמא תו אחר - ואז היא מצפצפת ומבטלת את ההקשה.אלא, שבגלל ריבוי הטסקטבוקסים, כמו גם הרצון "לעבוד נקי", לא כתבתי לשגרה זו Handles עבור כל טקסט בוקס - ידנית,
אלא כתבתי את שגרת KeyPressed בלי שום Handles שמעיר אותה, ובמקום זה בעליית התוכנה רשמתי את השורה הבאה:Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load HandleKeyPress(Me) End Sub
שבעצם קוראת לשגרה קטנה נוספת שהכנתי:
Private Sub HandleKeyPress(container As Control) For Each ctrl As Control In container.Controls If TypeOf (ctrl) Is TextBox Then AddHandler ctrl.KeyPress, AddressOf KeyPressed HandleKeyPress(ctrl) Next End Sub
עד כאן הכל עבד נפלא!
אלא שחלה תפנית בעלילה כאשר הייתי צריך להוסיף לתוכנה גם פקדים מסוג NumericUpDown לצורך נושא עיגול סכומים.
ואז שמתי לב שכאשר אני כותב ידנית בתוך תיבת ה NumericUpDown, השגרה של KeyPressed נכנסת לפעולה למורת רוחי,
וזה למרות שאין לשגרת KeyPressed שום Handles בכלל, ומי ששולח אליה זה רק ה AddHandler מהדלקת התוכנה, והוא הרי מוגדר רק: "If TypeOf (ctrl) Is TextBox".רק אציין, שלשם הבדיקה, הוספתי ל If המדובר שורה נוספת שתוציא לי את השם של הפקד שכעת מטופל ב For Each, ולמותר לציין שה-NumericUpDown לא היה בין הפקדים שטופלו ע"י ה If הזה.
אז רבש"ע, איך השגרה הזו מופעלת? מי קורא לה?
תודה רבה! -
אתה מריץ את הלולאה רקורסיבית על כל פקד.
לפקד NumericUpDown יש במאפיין Controls שתי פקדים, מהסוגים UpDownButtons, וUpDownEdit, האחרון יורש מTextBox.
כדי להגיע רק לTextBox ולא ליורשים ממנו יש להשתמש בהשוואה ממש ככה:If ctrl.GetType() = GetType(TextBox) Then