שאלה לגבי Events ב-Class

גרי רשף

New member
שאלה לגבי Events ב-Class

רקע כללי: יש Class הקורא אותות מרכיב חומרה (בעזרת DLL שהיצרן סיפק) על ידי לולאה אינסופית שקוראת בכל פעם, ויש צורך שה-Class יגרום להיווצרות ארוע (Event) כשיש שינוי בקריאה. אם אני מבין נכון- כשם שבתוכנית יש פרוצדורה המטפלת בארוע OnClick של פקד מסויים, כך יש צורך בפרוצדורה שתטפל בארוע OnCallChanged של ה-Class. כיצד מגדירים ויוצרים ארוע כזה? מדובר בתנאי (אם הקריאה הנוכחית שונה מהקודמת) שאם הוא מתקיים- יצור ארוע (?Raise Event).
 

sharkyM

New member
תגדיר event בצורה הזאת:

public class HardwareListener { private object _lastRead = null; public EventHandler CallChanged = null; protected OnCallChanged(object sender,EventArgs e) { if (CallChanged != null) CallChanged(sender,e); } // listen to the hardware public void Listen() { while (...) { object newResult = ....; if (newResult != _lastRead) OnCallChanged(this,new EventArgs()); } } }​
זהו מימוש פשוט, כמובן שהרבה יותר נחמד ליצור custom eventArgs המכיל property שבו יש את התוצאות החדשות, וכמובן יש ליצור אז delegate מסוג חדש.
 

גרי רשף

New member
תודה ואני כבר רץ לנסות..

..ואם אצליח- אנסה גם את הדברים הנחמדים יותר..
 

גרי רשף

New member
כמובן שלא הצלחתי../images/Emo8.gif

נתחיל עם תיקונצ'יק- צריך להיות protected void OnCallChanged (ועם זה אפילו אני יודע להתמודד). כיצד מגדירים ארוע בטופס הראשי? כיצד גורמים לכך שקיום התנאי יפעיל ארוע בטופס? מה לרשום ב-InitializeComponent של הטופס? כרגע זה עובד, אבל הארוע מופעל בתוך ה-Class.
 

yuval k

New member
הראה קצת קוד...

עקרונית, את האירוע אתה מגדיר כמו כל אירוע אחר שמוגדר שם, וזה אמור לעבוד.
 

גרי רשף

New member
דוגמה

SharkyM הציע את הקוד הבא:
public class HardwareListener { private object _lastRead = null; public EventHandler CallChanged = null; protected void OnCallChanged(object sender,EventArgs e) { if (CallChanged != null) CallChanged(sender,e); } // listen to the hardware public void Listen() { while (...) { object newResult = ....; if (newResult != _lastRead) OnCallChanged(this,new EventArgs()); } } }​
מיקמתי את הקוד עם השינויים המתבקשים ב-Class חדש. כשהתנאי שבלולאת ה-While מתממש המערכת פונה ל-OnCallChanged וחוזרת ללואה. כל זה בתוך ה-Class. כיצד אני כותב מחוץ ל-Class (נניח ב-Form1) פרוצדורה private void HardwareListener_OnCallChanged שתופעל כשהארוע הנ"ל קורה, בדיוק כשם שהפרוצדורה private void button1_Click מופעלת כשלוחצים על הפקד button1? יש לי רושם שאני מנסה לעשות משהו בלתי אפשרי כי אינני מבין מה המערכת עושה. יכול להיות שמה שאפשר עם הארועים של הפקד אינו אפשרי עם הארועים של ה-Class כי הפקד הוא כבר dll מקומפל וה-Class לא?
 

yuval k

New member
הא...

הקוד ששארקי הציע מממש מחלקה, שחושפת החוצה מאפיין בשם CallChanged מסוג EventHandler. כאשר קורה התנאי שמביא להפעלת האירוע, הפונקציה ש-CallChanged, שהוא למעשה delegate, מצביע עליה, נקראת. אתה יכול לשייך ל-CallChanged כל מתודה שתבחר בטופס שלך, בדיוק באותו אופן שאתה משייך מטפל אירוע לכל אירוע אחר:
HardwareListener listener = new HardwareListener(); listener.CallChanged += new EventHandler(HardwareListener_OnCallChanged);​
 

גרי רשף

New member
משהו עדיין חסר..

אני מבין שאת שתי שורות הקוד האלו אני רושם ב-InitializeComponent. אני מקבל הודעת שגיאה בשורה הראשונה מפני שה-type בשם HardwareListener לא נמצא.
 

גרי רשף

New member
עדיין לא..../images/Emo7.gif

הוא לא מקבל שם רפרנס ל-Class עם סיומת cs אלא רק ל-dll וכו'.. אני מצרף את צילום המסך כדי שזה יהיה ברור: הקוד אליו התייחסתי קודם נמצא (כפי שאפשר לראות) ב- EruaPashut.cs ואני רוצה ליצור ארוע private void HardwareListener_OnCallChanged בטופס Form1.
 
למעלה