כל מפתח שכתב Xaml נתקל בבעיה הבאה:
Property מסוג bool שעושים לו binding ל visibility של אלמנט כלשהוא.
הפיתרון לבעיה הזאת פשוט מאוד ולכן בכל תוכנה שכתובה ב xaml תמצאו את השורה הבאה:
Visibility="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}
יצירת converter היא באמת הפיתרון המתבקש כאן ,
אבל בואו ננסה ללמוד משהו מהמקרה הזה שחוזר על עצמו איןספור פעמים בכל חתיכת Xaml אי שם בעולם הפיתוח.
בעצם הבעיה היא ש Visibility Property לא יודע לתרגם את הטיפוס שהוא מקבל לטיפוס Visibility (שהוא במקרה שלנו enum).
פעולת התרגום מתבצעת על ידי Type conversion בצורה הבאה:
על כל טיפוס שאנו מעוניינים שהוא יהיה מסוגל לטפל בטיפוסים אחרים אנו שמים TypeConverterAttribute.(אפשר לשים ברמת הclass או ברמת הproperty)
TypeConverterAttribute מקבל פרמטר אחד , מחלקה אשר יודעת לבצע את התירגום שאנו מבקשים.
לדוגמא:
[TypeConverter(typeof(VisibleTypeConverter))]
public Visibility Visible
{
get
{
return (Visibility)this.GetValue(VisibleProperty);
}
set
{
this.SetValue(VisibleProperty, value);
}
}
public class VisibleTypeConverter : TypeConverter
{
{
לכן מה שהיינו מצפים שיהיה ב Visibility property הוא TypeConverter שיודע לתרגם "true"/"false" לערך הרצוי.
דוגמא טובה לכך היא שימוש ב margin,
Margin מקבל Thinckness struct , אז איך הוא יודע לתרגם את הדבר הבא ",0,2,2,1" ?
ובכן , כך זה נראה ב reflector :
[TypeConverter(typeof(ThicknessConverter)]
public struct Thickness : IEquatable<Thickness>
ומעתה , כל מי שישתמש ב thickness מקבל קיצור דרך לשימוש ב property !
אך לצערנו המצב הוא לא כך ב Visibility ולכן אנו נאלצים לכתוב ValueConverter בכל מקרה ומקרה שחוזר על עצמו עשרות פעמים בכל מערכת.
טוב, אז אם לא הצעתי פיתרון לבעיה , מה בעצם באתי להגיד פה?
ובכן, כמו שהזכרתי קודם, אנו צריכים ללמוד מהמקרה הזה, שכשאנחנו כותבים user control משלנו שנועד לשימוש בכמה וכמה מקומות במערכת, תמיד לחשוב על מי שצריך להשתמש בו, אפשר להכניס typeConverter שימיר "2,8"Grid = ליצירת Grid עם 2 עמודות ו 8 שורות למשל .
אולי בהמשך אתן דוגמאות בנושא.
.
No comments:
Post a Comment