May 2007 - Posts
נכחתי היום בהרצאה של תומר שמם על WPF. ראשית, אחלה הרצאה. סקירה יפה של WPF, XAML ויכולותיו. ממליץ בחום.
בתחילת ההרצאה, תומר דיבר על כך שאפליקציות WPF, בניגוד לאפליקציות WinForm - אינן מאפשרות עבודה עם כלי UI Spy למניהם, דבר שמקשה על מפתחי UI ומפתחי בדיקות אוטומטיות.
לפני כחצי שנה נתקלתי בבעיה הזאת כאשר הייתי צריך לעקוב אחר הRouted Events של אפליקציה של לקוח. במסגרת חיפוש קצר בגוגלטרנט, מצאתי את הכלי הOpen Sourceי Snoop (של פיט בלויס), שבעצם מאפשר צפיה בכל עץ האובייקטים של הWPF, בRoutedEvents, כמובן שבProperties של כל אובייקט ומציג Preview של כל אובייקט בחלון קטן (ומאפשר לעשות Zoom). כלי חובה לכל מפתח WPF.
קישור ישיר להורדת הפרויקט.
Technorati tags:
WPF,
Snoop,
XAML,
UISpy,
Spy++
נכנסתי כרגע ונראה שהעיצוב השתנה... כנראה בכמה שעות האחרונות. עדיין לא החלטתי אם זה יותר נוח, אבל.. זה בהחלט נראה KISS.
בקרוב אעלה כאן סדרת פוסטים בנושא Virtual Earth - היכולות הGISיות, אך כהקדמה - דבר מעניין שנתקלתי בו.
שיקולים בבחירת מנוע GIS, בשתי מילים:
ובכן, רבים מאיתנו (או לפחות, מפתחי הGIS שביננו) בוודאי מכירים את הדיסוננס שבבחירת תשתית GIS לפרויקט. ישנם המון פרמטרים שארכיטקט בפרויקט תשתית גיאוגרפי צריך לקחת בחשבון, בינהם:
- סדרי הגודל של המידע שיוצג על המפה.
- כמות האובייקטים שיצויירו בזמן אמת על המפה, ואופיים (מטרות נייחות או ניידות?).
- דרישות ההפצה של המערכת, בעיקר בהיבט הLicense - ובסעיף הזה אני כבר אכליל את עלויות הפיתוח.
- התמיכה הטכנית והסטנדרטיזציה.
ארגונים נוטים לעתים לבחור בתשתית בגלל שהיא נפוצה יותר, בגלל שיועצי אחיטופל למניהם בחרו בתשתית הזאת ובגלל אנשי שיווק מאוד מוצלחים. לא אטען לרגע שהשיקולים האלו לא נכונים, אך לדידי - הארגון נוטה להכנס להריון עם המוצרים האלו, ומגלה את הטעות כשכבר לא ניתן לעשות הפלה.
ובשתי מילים - איכסה פיכסה.
הבעיה ההנדסית
אחת הבעיות ההנדסיות הגדולות, הן ריכוז המידע הגיאוגרפי במקום אחד. תשתיות כמו ArcEngine Runtime, ArcGIS של ESRI תומכות בצורה מאוד מצומצמת בביזור התשתיות הגיאוגרפיות.
כך לדוגמא, במידה ונרצה להפיץ מערכת מבוזרת - ייתכן שנאלץ לספק עבור כל עמדת לקוח את המידע הגיאוגרפי הרלוונטי, או שנאלץ לבצע את הסריאליזציה על התווך בעצמנו, נשמור BLOBים של מידע בDB ונפספס חלק גדול מהיתרון שבשימוש בקוד Legacy שמגיע כחלק מהחבילה.
הרצון בכל זאת לא להמציא את הגלגל (ולא לנהל פרויקט תוכנה על פני עשור) עשוי לעלות המון כסף. פתרונות כמו Arc Server/ArcSDE יעלו עשרות אלפי $, וחוזי התחזוקה ירוששו כל מי שאין לו עתודות מתאימות.
כמובן שיש פתרונות של עוד חברות (בינהן גם ישראליות) לתחום, אך כולם יקרים בסדרי גודל ממה שאציג כאן.
ש: Katmai? ת: מדבר!
אתמול קראתי לתומי את הSpec שפורסם עבור SQL Server 2008 Codename 'Katmai', והופתעתי לראות סעיפון קטן, גור סעיפים, שבמשפט אחד מציין שנות אדם בשבילי:
Deliver Location Intelligence
Geographical information is rapidly becoming
main stream to many business applications.
In “Katmai”, SQL Server provides new spatial
data types for developers to build locationaware
applications.
כמובן שהשלב הבא היה להעמיס על גוגל +Katmai +Spatial ולקבל קישורלבלוג של Virtual Earth, שם מצאתי מעט מידע נוסף, אך עדיין - לא מספיק (כתוב שם שכרגע המידע מסווג מסחרית.. נקווה שנזכה לראות אותו באינטרנט לפני הTechReady 5).
בגדול, הנקודות שהועלו:
- תמיכה במסד נתונים גיאוגרפי (לא צויין אופי התמיכה, אך כן צויין שהוא יהיה OGC Friendly לפחות בגרסה הדו מימדית שלו).
- תמיכה בProjection.
- תמיכה במודל גאודטי.
- תמיכה בSpatial Indexing הן בגרסה הדו מימדית והן בתלת.
מה המשמעות? במחיר Licensing רגיל של SQL, אנחנו מקבלים את מה שעד היום עלה לנו המון, ולפעמים - הפיל פרויקטים או גרם לרגרסיה בדרישות התוכנה. האם השילוב של זה וVirtual Earth מייצר מתחרה ראוי לIMS של ESRI עבור פרויקטים בינוניים ומטה?
הצעצוע הזה מאפשר לכם להפוך את התמונות הסטטיות שלכם למשהו מעט יותר דינאמי (מאפשר הגדלה/הקטנה, קביעת כיתובים ואפילו - פרסום על-גבי התמונה תמורת תשלום).
לפני:
אחרי:
הצעצוע זמין כאן: BritePic.
קרדיט: אייל ש.
ואחרי שצחקנו, נעבור לחלק האומנותי - איך לקבוע האם הפקד שיצרנו רץ בDesigner כרגע, או באפליקציה רגילה.
כל תחום הDesigner בWPF לא מזכיר את מה שהיה קודם לכן עבור WinForm. הבעיה שלי התחילה בפעם הראשונה שייצרתי פקד בWPF. הפקד אמור היה לשמש אנשי UI בExpression Blend, ז"א - הוא היה צריך להיות מאוד מאוד פשוט. כמה שפחות Properties שזמינים לעריכה וכמה שיותר דברים שהוא ידע לעשות אוטומטית (כמו Docking בתוך Panel וכו').
השלב הראשון בעבודה היה כמובן - לזהות מתי אני בDesigner כדי שאוכל לספק התנהגויות שונות (כמו מסגרת, חלון עריכה מוסדר וביצי פסחא עבור צירופי מקשים מסויימים).
כדי להבין מה חדש בWPF - נתחיל בסקירה של מה שהיה:
בעבר, כל UserControl מימש Property בשם DesignMode, שהחזיר true במידה והפקד היה (באופן מפתיע) בDesigner. במימוש הזה היו שתי בעיות (וחצי):
- לא ניתן היה לקבל סטטוס מדוייק בתוך הConstructor של הפקד. זאת משום שProperty קיבל ערך רק אחרי שהDesigner בצע Deserialization לקוד שכתוב בתוך הInitializeComponents (אגב, אני מקווה לכתוב בעתיד פוסט על הסריאליזציה שמתבצעת בInitializeComponents).
- Nested Controls שנוצרו תחת פקד אחר לא ידעו להחזיר את מצבם.
- חצי בעיה נוספת - בעבר, הDesigner היחיד היה הIDE של VS. בWPF אנחנו לראשונה נתקלים במצב בו יש יותר מDesigner אחד (Expression, VS בתור התחלה). מה קורה אם אני רוצה לדעת בדיוק באיזה Designer אני עובד ולא רק האם אני נמצא באחד?
כך עשינו זאת בWinForms:
קוד:
public class CustomButton : Button
{
public CustomButton()
{
if (this.DeisgnMode)
{
this.Text= "In Design Mode";
}
else
{
this.Text= "Runtime";
}
}
}
הפתרון שהומצא עבור WPF באחד הCTPים הראשונים:
הפתרון הראשוני שנמצא לבעיות שהוזכרו לעיל היה... לסבך את העסק. מחד גיסא, כמו שהתבקש - הפרמטר הפך לגלובאלי, ז"א - בכל מצב ניתן היה לחלץ את מצב הריצה של התוכנית מהAppDomain. מאידך גיסא - זה הוחזר כDependencyProperty שזה קצת איכסה. (אגב, גם בWinForms ניתן לקבל את הפרמטר הזה גלובאלית, דרך הLicenseManager. אם תהיה דרישה, אכתוב גם על זה פוסט בעתיד).
כך זה היה נראה אלמלא תושיה של אחד הטוקבקיסטים בבלוג של UrbanPotato:
קוד:
bool IsDesignMode {
get {
DependencyProperty isDesignModeProperty = (DependencyProperty)AppDomain.CurrentDomain.GetData(“IsDesignModeProperty”);
return isDesignModeProperty == null ? false : true.Equals(isDesignModeProperty.GetValue(this));
}
}
ומכאן, הדרך כבר הייתה סלולה לפתרון שזמין היום:
תחת הComponentModel הוכנסה המחלקה DesignerProperties שמציעה לנו בין היתר את GetIsInDesignMode. הפונקציה תחזיר bool עם התשובה.
וכך זה ייראה מהיום והלאה (או לפחות, עד הפעם הבאה שמיקרוסופט תעצור לשימון צירים):
קוד:
public class CustomButton : Button
{
public CustomButton()
{
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
Content = "In Design Mode";
}
else
{
Content = "Runtime";
}
}
}
את ההודעה כתבתי במקור בפורום תיכנות אותו אני מנהל באתר פרש (שגם אותו אני מנהל).
מסתבר שזה לא כ"כ פשוט לכתוב את ההודעה הראשונה בבלוג. מחד, אתה רוצה משהו מספיק שנון בשביל שמי שיתקל בבלוג ירצה לחזור ולבדוק עדכונים. מאידך, אתה רוצה לספר על עצמך מעט... ומה כבר יכול להיות שנון בזה?
אז החלטתי לשתף אתכם בחוויות הלילה שלי על כביש החוף.. כי זה הרי מעניין את כולם.
בשעה 23:00 יצאתי סוף סוף מהמשרד (אחרי שסיימתי לדבג לESRI את ArcGIS - מה שאומר שהבלוג הזה ייגע גם קצת בGIS). שמח וטוב לבב, נסעתי מהמשרד לכיוון משרדי החברה (באור יהודה) לאסוף את המחשב שלי שהשארתי שם. משם, המשכתי לכיוון הדירה ברמת-גן, לאסוף את חומר הלימוד (האוניברסיטה הפתוחה, שנה 19 מתוך 35). משם... סוף סוף עליתי על אלוף שדה לכיוון חיפה, משכנם של הוריי אצלם אעביר את סוף השבוע הזה.
ברדיו ניגנו משהו כנראה.. אני אותו זמן הייתי עסוק בשיחות עבודה עם מאן-דהם. פרט מרתק נוסף היה הגשם שהמטיר לכלוך על כל הנוסעים - ובוץ על הכביש, מה שבאופן טבעי גורם לאנשים לבלום בלימות חירום בתוך הרכב שלפניהם.
במשך 45 דקות עמדתי על כביש החוף (בחצות בערך) עד קצת אחרי M הדרך, מבין שאני כבר לא "אתקתק את הנסיעה הזאת בפחות משעה".
בינתיים, שיחות העבודה נגמרו מה שגרר שיחות עם חברים שערים בשעות האלו.. או ליתר דיוק - התעוררו בשעות האלו.
הגעתי ללובי של חיפה (עתלית) שם זכיתי לליווי צמוד של ניידות משטרה ורכבים של מע"צ. כמובן שעבודות בכביש הם דבר מלחיץ, ולכן שני נהגים החליטו שהם רוצים לאחד את השלדות שלהם בדיוק באיזור בו סוללים.
התוצאה? 4 ניידות משטרה ועוד 30 דקות עד שפילסו נתיב ונתנו לנו לעבור.
סה"כ - נסיעה שהתחילה ב23:30 לערך והייתה אמורה להסתיים ב00:30 לכל היותר, הסתיימה ב1:45.. ובנס - אין נפגעים לכוחותינו.
אה.. אגב.. אני דורון.