שאלה:
לא ניתן להשתמש ב - CrossPostBack בדפים שמשתמשים ב - MasterPage,
כלומר אם הדף השולח הוא עם MP, הדף שנשלחים אליו הנתונים לא יזהה את הפקדים ב PreviousPage כאשר נעבוד עם this.PreviousPage.FindControl,
האם מישהו מכיר פתרון לבעיה הזו
תשובה:
FindControl אינו מבצע חיפוש היררכי בתוך Container אלא מבצע חיפוש בן רמה אחת בלבד בתוך בניו הישירים של Container. כאשר אין MasterPage אז this.PreviousPage יבציע ל-Form שהוא ה-Container העליון בדף הכתוב. כאשר יש MasterPage אז this.PreviousPage יצביע ל-MasterPage עצמו שהוא בתוכו מכיל את ה-Form וכך הלאה.
זאת אחת מהסיבות הרבות שלא צריך להשתמש ב-FindControl (התלות במיקום היחסי של פקדים). עוד סיבה טובה היא העובדה ש-FindControl הוא loosly typed שמבוסס על מחרוזות ולא על דברים שבאמת עוברים קומפילציה. ככה שאם נכתוב אפליקציה שמשתמשת ב-FindControl ואז חס וחלילה נשנה את שם הפקד או מיקומו האפליקציה לא תעבוד, אבל גם תעבור קומפילציה.
הפתרון הפשוט והבעייתי של המצב הזה הוא לחפש את אלמנט ה-form בתוך ה-MasterPage ובתוכו לחפש את הפקד שלך (וכך הלאה בכל רמת קינון נוספת שבתוכו יושב הפקד). תוכל לגלות את הנתיב "הנכון" (ביחס לאותה שנייה בה אתה מפתח את האפליקציה) באמצעות נבירה וחיפוש ב-PreviousPage.Controls במצב דיבאג עד שתגיע לפקד שאתה מחפש.
הפתרון הנכון במקרה הזה הוא שוב עבודה עם מאפיינים. נגיד ויש לנו טופס Content1.aspx שיש בו כפתור ואנחנו רוצים לגלות מה הטקסט של הכפתור בדף Content2.aspx שאליו נבצע Cross Page PostBack. ברמת Content1 נחשוף מאפיין שיציג את הטקסט של הכפתור שאותה ינצל Content1.
public partial class Content1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string ButtonText
{
get
{
return Button1.Text;
}
}
}
בטעינה ב-Content2 נבדוק שבאמת מדובר ב-Cross Page PostBack ואם כן ניקח את הדף הקודם ונמיר אותו לסוג Content1 ובכך נקבל גישה למאפיין החדש שלנו.
public partial class Content2 : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if (this.PreviousPage != null)
{
Content1 myPreviousPage = (Content1) PreviousPage;
Response.Write(myPreviousPage.ButtonText);
}
}
}
הסיבה לביצוע ההמרה היא כמובן ש-PreviousPage הוא מסוג System.Web.UI.Page שאינו מכיל את המאפיין החדש שלנו ואלינו לדאוג לבצע את ההמרה מ-Page לסוג דף הספציפי שלנו בכדי שנקבל גישה תכנותית למאפיין החדש. בדומה לדוגמה הקודמת נדאג גם לא להעתיק ממקום למקום את ההמרה של Previous Page ונדאג ליצור אותו מחדש ברמת Conten2.
public partial class Content2 : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
//if (this.PreviousPage != null)
//{
// Content1 myPreviousPage = (Content1)PreviousPage;
// Response.Write(myPreviousPage.ButtonText);
//}
if (this.PreviousPage != null)
Response.Write(this.PreviousPage.ButtonText);
}
private new Content1 PreviousPage
{
get
{
if (this.PreviousPage == null)
return null;
return (Content1) this.PreviousPage;
}
}
}
יש גם סיבה הרבה יותר תיאורטית ללמה זאת צורת עבודה נכונה והיא קשורה למילים גבוהות וגדולות כמו Cohesion גבוה בתוך כל דף (שהוא מארז בפני עצמו לפי מודל הקומפילציה) ו-Coupling נמוך בין הדפים עצמם. במילים של בן-אדם נורמלי, זה אומר שאנחנו רוצים שכל דף יהיה אחראי כמה שיותר לעצמו ולא ליצור תלות מיותרת בין הדפים. למשל אם נשתמש ב-FindControl בדף Content2.aspx נקבל מצב ששינוי במבנה ההירכי של פקדים ב-Content1.aspx או בשם הפקדים יגרור לכך ש-Content2.aspx יכשל בצורה שקטה. לעומת זאת כאשר Content1.aspx חושף רק את המידע הרלוונטי לדפים שמשתמשים בו והוא אחראי שהמידע הנכון יחשף אנחנו יוצרים תוכנה שיהיה הרבה יותר קל לתחזק והרבה יותר עמידה לשינויים.
קישור: http://www.tapuz.co.il/tapuzforum/main/Viewmsg.asp?forum=831&msgid=87412250