מדריך Windows Phone

מדריך Windows Phone – שימוש ב Resources

‏ • Sela

לפני שנתחיל נעיר כי ה Resources שאנו מדברים עליהם בפרק זה אינם קשורים בכלל ל Project Resources שאולי אתם מכירים מעידן הקודם ל WPF ו Silverlight. השימוש בProject Resources מיועד בעיקר להוספת תמונות וטבלת מחרוזות (strings) שניתן לבצע להם לוקליזציה (תרגום לשפה מקומית). ה Resources שאנחנו נדבר עליהם בפרק זה הם תכונה ייחודית לטכנולוגיות מבוססות XAML.

מה זה Resources?

שימוש ב Resources מאפשר לנו לעשות שימוש חוזר באובייקטים שיצרנו. ע"י שימוש ב Resources נוכל לחסוך בזיכרון (פחות אובייקטים ישבו בזיכרון), לחסוך בזמן (עצם היצירה של אובייקטים לוקחת זמן), וכן לחסוך בכתיבת קוד (הגדרה של אובייקטים יכולה להיות מורכבת וחבל לחזור עליה שוב ושוב).

נראה דוגמא שבה נרצה להשתמש ב Resources. בקוד הבא אנו מגדירים טופס לקבלת נתוני User ו Password של משתמש, וקבענו רקע צבעוני במיוחד לשני ה TextBox בתוכנית. השימוש במחלקה LinearGradientBrush ליצירת רקע מתחלף ילמד בהמשך המדריך. כרגע מה שחשוב לשים לב הוא שאותה הגדרה מורכבת של האוביקט LinearGradientBrush מופיעה פעמיים בקוד הXAML:

<phone:PhoneApplicationPage
  x:Class="PhoneDemo.MainPage"
  >="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  >:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  >:d="http://schemas.microsoft.com/expression/blend/2008"
  >:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  d:DesignWidth="480"
  d:DesignHeight="800"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  Orientation="Portrait"
  SupportedOrientations="Portrait">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition
       Height="Auto" />
      <RowDefinition
       Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition
       Width="*" />
      <ColumnDefinition
       Width="*" />
    </Grid.ColumnDefinitions>
    <TextBlock
     Text="User:"
     Grid.Row="0"
     Grid.Column="0" />
    <TextBox
     Grid.Row="0"
     Grid.Column="1">
      <TextBox.Background>
        <LinearGradientBrush>
          <GradientStop
           Color="Blue"
           Offset="0" />
          <GradientStop
           Color="Yellow"
           Offset="0.5" />
          <GradientStop
           Color="Red"
           Offset="1" />
        </LinearGradientBrush>
      </TextBox.Background>
    </TextBox>
    <TextBlock
     Text="Password:"
     Grid.Row="1"
     Grid.Column="0" />
    <TextBox
     Grid.Row="1"
     Grid.Column="1">
      <TextBox.Background>
        <LinearGradientBrush>
          <GradientStop
           Color="Blue"
           Offset="0" />
          <GradientStop
           Color="Yellow"
           Offset="0.5" />
          <GradientStop
           Color="Red"
           Offset="1" />
        </LinearGradientBrush>
      </TextBox.Background>
    </TextBox>
  </Grid
>
</
phone:PhoneApplicationPage
>

מדריך Windows Phone – שימוש ב Resources

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

כיצד נגדיר Resource?

כמעט לכל פקד ב Silverlight יש Property בשם Resources. הטיפוס של תכונה זו הוא Dictionary. כלומר ניתן להכניס לתכונה זו זוגות של מפתח (Key) וערך (Value).

כדי להוסיף אובייקט לResources של פקד נשתמש בקוד הבא:

  <phone:PhoneApplicationPage.Resources>
    <LinearGradientBrush
     x:Key="myLinearGradientBrush">
      <GradientStop
       Color="Blue"
       Offset="0" />
      <GradientStop
       Color="Yellow"
       Offset="0.5" />
      <GradientStop
       Color="Red"
       Offset="1" />
    </LinearGradientBrush>
  </phone:PhoneApplicationPage.Resources
>

הוספנו את האובייקט LinearGradientBrush שלנו תחת תכונת Resources של הדף ובנוסף הוספנו לו תגית x:Key כדי לתת לו מפתח שיזהה אותו. יותר מאוחר אנחנו נשתמש במפתח הזה כדי לפנות לאובייקט.

נעיר כי ניתן לשים אובייקטים בתכונת Resources של כל פקד שיש לו את התכונה הזו, אבל לרוב אנו נשים את האובייקטים במקום מרכזי כמו באובייקט הדף הראשי (PhoneApplicationPage) או באובייקט האפליקציה (App).

כיצד נשתמש ב Resource שהגדרנו?

כדי להשתמש בResource שהגדרנו נכתוב את הקוד הבא:

<TextBox Grid.Row="0"
Grid.Column="1"
Background="{StaticResource myLinearGradientBrush}"
>

במקום להגדיר את כל האובייקט LinearGradientResource תחת התכונה Background כמו מקודם, כל מה שצריך לעשות להשתמש בתגית המיוחדת StaticResource ולאחריה לתת את המפתח שמזהה את האובייקט המבוקש. כמובן שניתן לפנות לאובייקט ממספר מקומות שונים (זאת הייתה המטרה מלכתחילה).

להלן הקוד המלא של הדוגמא המתוקנת:

<phone:PhoneApplicationPage
  x:Class="PhoneDemo.MainPage"
  >="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  >:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  >:d="http://schemas.microsoft.com/expression/blend/2008"
  >:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  d:DesignWidth="480"
  d:DesignHeight="800"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  Orientation="Portrait"
  SupportedOrientations="Portrait">
  <phone:PhoneApplicationPage.Resources>
    <LinearGradientBrush
     x:Key="myLinearGradientBrush">
      <GradientStop
       Color="Blue"
       Offset="0" />
      <GradientStop
       Color="Yellow"
       Offset="0.5" />
      <GradientStop
       Color="Red"
       Offset="1" />
    </LinearGradientBrush>
  </phone:PhoneApplicationPage.Resources>
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition
       Height="Auto" />
      <RowDefinition
       Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition
       Width="*" />
      <ColumnDefinition
       Width="*" />
    </Grid.ColumnDefinitions>
    <TextBlock
     Text="User:"
     Grid.Row="0"
     Grid.Column="0" />
    <TextBox
     Grid.Row="0"
     Grid.Column="1"
     Background="{StaticResource myLinearGradientBrush}" />
    <TextBlock
     Text="Password:"
     Grid.Row="1"
     Grid.Column="0" />
    <TextBox
     Grid.Row="1"
     Grid.Column="1"
     Background="{StaticResource myLinearGradientBrush}" />
  </Grid
>
</
phone:PhoneApplicationPage
>

התגית StaticResource דואגת לחפש את האובייקט המבוקש ולהציב אותו בתור ערך לתכונה.

כיצד מתבצע תהליך החיפוש?

תהליך החיפוש של StaticResource עובד באופן הבא:

החיפוש משתמש במפתח כדי למצוא את האובייקט באחד הDictionary במעלה העץ.

ראשית מחפשים את האובייקט המבוקש (בדוגמא LinearGradientBrush ) בתכונה Resources של הפקד הנוכחי (בדוגמא TextBox), אם מצאנו את האוביקט ב Dictionary שלו התהליך מסתיים, אחרת החיפוש עולה רמה אחת בעץ הפקדים (בדוגמא Grid) ושוב מחפש בתכונה Resources, וכך התהליך ממשיך. בדוגמא שלנו, לאחר שהאובייקט לא נמצא ב Grid אנו מחפשים ב Resources של הPhoneApplicationPage ושם האובייקט נמצא ומוחזר בהצלחה.

אם האובייקט לא נמצא בשורש העץ שהוא לרוב מטיפוס PhoneApplicationPage אזי מתבצע חיפוש נוסף בקובץ הXAML של האפליקציה: App.xaml.

מתי מתבצע תהליך החיפוש?

כאשר אנו משתמשים בStaticResource תהליך החיפוש מתבצע כאשר Silverlight זקוק לערך של התכונה פעם ראשונה (לרוב בטעינת התוכנית), ואז מתבצע החיפוש על עץ הפקדים. לאחר החיפוש התוצאה נשמרת ולא מתבצעים יותר חיפושים בהמשך.

תגיות: , , , ,

arikp

אריק פוזננסקי הוא יועץ בכיר ומרצה בסלע. הוא השלים שני תארי B.Sc. במתמטיקה ומדעי המחשב בהצטיינות יתרה בטכניון. לאריק ידע נרחב בטכנולוגיות מיקרוסופט, כולל .NET עם C#, WPF, Silverlight, WinForms, Interop, COM/ATL, C++ Win32 ו reverse engineering.

תגובות בפייסבוק