Wednesday, October 16, 2013

Binding in DataTemplate using Tuple

הטריק הבא יכול להיות מאוד שימושי. נניח שאני מחזיק אובייקט שחלק ממנו זה Command פנימי ועוד ערכים. האובייקט נראה בערך כך:

public class MyCommandWrapper
    {
        public string Description;
        public ICommand Action;
        public object Data;
    }
 
ונניח שישי לי רשימה של אובייקטים מהטיפוס הזה:
 
List<MyCommandWrapper> CommandsWrappers = new List<MyCommandWrapper>();
 
ואני בונה DataTemplate שיציג את הפרופרטיז הרלוונטים אבל בין היתר יכיל כפתור שלחיצה עליו תפעיל את ה Command.
זה יראה בערך משהו כזה:

<DataTemplate x:Key="MyTemplate" >
          <RadioButton Command="{Binding Action}">
              <RadioButton.Style>
                  <Style TargetType="RadioButton">
                    <Setter Property="Content" Value="{Binding Description}"/> 
                  </Style>
              </RadioButton.Style>
          </RadioButton>
      </DataTemplate>

איפה הבעיה ?
נניח שקשרתי את הDataTemplate לאובייקט דרך שמות הפרופרטיז גם אם לא השתמשתי ב DataType .
 
ואם מחר אשנה את שמות האובייקט מודל שלי הBinding לא יעבוד..
ומן הסתם אפשרי גם שהאובייקט הזה הוא מודל כלשהו שאני מעדיף לשמור לעצמי ולא שיהיה חשוף בקבצי סטייל.
 
ובכן ניתן להשתמש ב <>Tuple שמתאר רק מבנה של אובייקט בלי להיכנס לשמות משתנים,  ז"א בשביל הדוגמא למעלה במקום להכריז על אובייקט שנקרא MyCommandWrapper , אני אחזיק
Tuple<string, ICommand, object> MyWrapperCommand;

ובהתאם,  רשימה של "טיפוסים" כאלה,
 
כל שנשאר זה לחזור לDataTmplate ולבצע שם את ההתאמות. מאחר שבמימוש של Tuple מופיעה רשימה גנרית של אלמנטים מסוג T שנקראים item1 , item2 וכן הלאה,
 
גם בDataTemplate נירשם לאותם שמות ברירת מחדל כי מה שקובע בזמן ריצה זה הטייפ שמוגדר אצלנו, תוך ידיעה שהראשון הוא string השני Command וכן הלאה.

<DataTemplate x:Key="MyTemplate" >
   <RadioButton Command="{Binding item2}">
       <RadioButton.Style>
           <Style TargetType="RadioButton">
             <Setter Property="Content" Value="{Binding item1}"/> 
           </Style>
       </RadioButton.Style>
    </RadioButton>
</DataTemplate>


QR: Inline images 1