RSS

Silverlight Validation & Data Annotation

16 יונ

Silverlight Validation & Data Annotation

בשבוע האחרון נתקלתי במספר שאלות על נושא Validation ולכן החלטתי לעשות סדר ולהסביר את המנגנון שנמצא ב-SL .

אחד התפקיד העיקרים של ה- Validation בשכבת ה-UI הוא לבדוק נכונות של הנתונים שמוזנים ע"י המשתמש.
היום הדרך השכיחה ביותר לחיבור בין הפקדים לאוביקטים שמחזקים את המידע הוא שימוש ב- DataBinding. מכאן נובע שמיקרוסופט כדי להקל אלינו הכניסה בתוך האוביקט Binding יכולות של Validation.

clip_image002

אוביקט ה-Binding לקח את הערך מפקד ה-UI למשל TextBox, את הערך מהפרופרטי Text ומכניס אותו לאוביקט שלנו. עכשיו נשאל את השאלה מי עושה לערך המוכנס את ה- Validationואיך מדווחים על שגיאות?

יש מספר דרכים לעשות את הבדיקות לערך המוכנס:

1. בדיקה רגילה בתוך ה-Set של ה-Property ( Databinding עובד רק על פרופרטי Public)

clip_image004

2. עבודה עם Attributes ששיכים למשפחת Data Annotation

clip_image006

כיום העבודה עם Data Annotation היא הדרך הפופולרית יותר, בגלל הפשטות והיכולת לעבוד עם סיפרית ה-Attribute גם בצד השרת וגם בצד הלקוח. WCF RIA Services ו- ASP.NET MVC עובדים עם טכנולוגיה זו.

כאשר הבדיקה נכשלת איך מדווחים לשכבת ה-UI שהערך המוקלד לא נכון? להלן מספר דרכים לפתרון:

1. זריקת טעות
ע"פ דעתי זו הדרך הגרועה ביותר כי זריקת Exception בתור ה-Set של הפרופרטי מעקב את ה-UI ויש בתוך ה- Exceptionיותר מידע ממה שצריך. כדי שה-Binding יתיחס לשגיאות צריך להדליק אופציה זו.

<TextBox Text="{Binding Model, ValidatesOnExceptions=True} />

2. עבודה עם ממשק IDataErrorInfo ( ישן ולא נוח )
clip_image007

באחריותך לדאוג לעדכן את Error פרופרטי, אם יש מספר טעויות באחריותכם לקבוע סימון מפריד בין הודעה להודעה כי Error מחזיר string. גם ה-Indexer מעצבן כי אני צריך אותם לדברים אחרים.

כדי שה-Binding יתיחס לשגיאות צריך להדליק אופציה זו.

<TextBox Text="{Binding Model, ValidatesOnDataErrors=True}" />

3. עבודה עם ממשק INotifyDataErrorInfo
clip_image009

הרבה יותר נוח מהקודם בגלל האירוע שמדווח לי שיש בעיה ואז אני יכול למשוך את כל הבעיות דרך המתודה GetErrors ע"פ הפרופרטי הרלוונטי. כדי שה-Binding יתיחס לשגיאות צריך להדליק אופציה זו. (ValidatesOnNotifyDataErrors=True, זה ערך בברירת המחדל )

<TextBox Text="{Binding Model, ValidatesOnNotifyDataErrors=True}" />

ב-WPF לא קיים INotifyDataErrorInfo, אני מקווה מאוד שבגירסה 5 הם יוסיפו אותו.

4. עבודה עם אוביקט Validator
ב-SL רק הפקד DataGrid יודע לעבוד עם Data Annotation כל שאר הפקדים מצריכים מאיתנו לכתוב קוד שיודע להבין את Attribute ולפעול בהתאם. לשם כך נשתמש במחלקה Validator.
כדי שה-Binding יתיחס לשגיאות צריך להדליק את האופציות הבאות:


<TextBox Text="{ Binding Model,
ValidatesOnExceptions = True,
NotifyOnValidationError= True }" />

מה עושה, NotifyOnValidationError= True? מפעיל Routed Event כדי לדווח לאבא.

clip_image010

clip_image012

הבעיה כאן שהמחלקה Validator זורקת טעות, וזה לא לטעמי, מהסיבות שפרטתי בסעיף 1. כדי שלא יהיה לנו Exceptions אנחנו צריכים לעבוד עם המתודה TryValidateProperty. הבעיה שאז איך ה- Binding ידע על השגיאות? התשובה לעבוד עם אחד הממשקים, וב-SL כמובן שנבחר ב- INotifyDataErrorInfo. אם מסתכלים על המתודה TryValidateProperty אנחנו רואים שהיא מקבלת <ICollection<ValidationResult ששם מאוחסנים כל הטעויות של Validation. לכן הממשק INotifyDataErrorInfo השתמש במאגר זה לדווח על טעויות. לדוגמא לכך אפשר לקרוא בפוסט Silverlight 4 MVVM Validation using INotifyDataErrorInfo.

עד כאן הסברתי איך מתבצעת ה-Validation ואיך אוביקט ה-Binding מזהה שיש בעיה. מה שנשאר לנו להבין, איך הפקדים מסמנים שיש בעיה? איך אפשר לשנות עיצוב זה?

כמעט לכל הפקדים שיכולים לקבל Input יש מצב של טעות (InvalidFoucused & InvalidUnfocused) שבעזרת Blend אפשר לשנות עיצוב זה בקלות.

clip_image013
השאלה שנשאלת היא מי מעביר את ה-State למצב של InvalidFocused? האם זה ה-Binding או הפקד עצמו? התשובה היא שה- Bindingזורק אירוע שנתפס ע"י הפקד, והפקד מעביר את עצמו למצב של InvalidFocused או InvalidUnfocused. אם אנחנו רוצים גם להירשם לאירוע של השגיאות אנחנו נרשמים לאירוע ה- BindingValidationError שמוגדר ב- FrameworkElement.

סיכום:

אני מאוד אוהב את העבודה עם Data Annotation והתוספת שמחברת את השגיאות ל- INotifyDataErrorInfo. WCF RIA Services נותן לנו את זה בחינם, אך אין בעיה גם לכתוב את השורות אלו בעצמנו ב- ViewModelBase. פתרון עוד יותר נקי זה להכניס את זה לתוך הפקד כמו שעשו ב-DataGrid ו-DataForm.

מודעות פרסומת
 
השארת תגובה

פורסם ע"י ב- יוני 16, 2011 ב- Uncategorized

 

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

 
%d בלוגרים אהבו את זה: