מדריך Windows Phone – שימוש ב Data Templates
מה זה Data Templates?
Data Template הוא מנגנון המאפשר ליצור בזמן ריצה רכיבי UI מתוך Data. לדוגמא, בפרק הקודם ראינו כיצד ניתן לחבר פקד ListBox ל Collection של איברים מטיפוס MyData. נחזור על הקוד של הדוגמא:
המחלקה MyData הוגדרה באופן הבא:
namespace PhoneDemo
{
public class MyData
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsLecturer { get; set; }
public override string ToString()
{
return string.Format(
"First name: {0}, Last name: {1}, Is lecturer: {2}",
FirstName,
LastName,
IsLecturer);
}
}
}
קוד ה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"
>:local="clr-namespace:PhoneDemo"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
Orientation="Portrait"
SupportedOrientations="Portrait">
<StackPanel>
<ListBox
ItemsSource="{Binding}" />
<Button
Content="Add"
Click="Button_Click" />
</StackPanel>
</phone:PhoneApplicationPage>
הקוד מאחור ב#C:
using System.Collections.ObjectModel;
using System.Windows;
using Microsoft.Phone.Controls;
namespace PhoneDemo
{
public partial class MainPage : PhoneApplicationPage
{
private ObservableCollection<MyData> _myCollection = new ObservableCollection<MyData>();
// Constructor
public MainPage()
{
InitializeComponent();
DataContext = _myCollection;
_myCollection.Add(
new MyData
{
FirstName = "Arik",
LastName = "Poznanski",
IsLecturer = true
});
_myCollection.Add(
new MyData
{
FirstName = "John",
LastName = "Smith",
IsLecturer = false
});
}
private int counter = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
++counter;
_myCollection.Add(
new MyData()
{
FirstName = "item " + counter,
LastName = "item " + counter,
IsLecturer = counter % 3 == 0
});
}
}
}
תוצאת הרצת התוכנית הזו הייתה:
כעת נחזור לבעיה המקורית של התצוגה של אלמנט מטיפוס MyData. הבעיה בתצוגה של אלמנט זה הייתה שאלמנט זה אינו רכיב גרפי ולכן אינו יודע כיצד להציג את עצמו כראוי. כברירת מחדל, Silverlight קורא לפונקציה ToString של האובייקט MyData ומציג את התוצאה בתוך פקד TextBlock.
Data Template זוהי טכניקה המאפשרת לנו להגדיר כיצד אובייקט נתונים (לדוגמא, מטיפוס MyData) יראה בצורה גרפית.
כיצד נגדיר Data Template?
כדי להגדיר כיצד יש להציג אלמנטים מטיפוס MyData יש צורך להגדיר Data Template עבורו. להלן דוגמא:
<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"
>:local="clr-namespace:PhoneDemo"
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>
<DataTemplate
x:Key="MyDataTemplate">
<Border
BorderBrush="Red"
BorderThickness="5">
<Grid
Width="400">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Text="First Name: " />
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding Path=FirstName}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Text="Last Name: " />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path=LastName}" />
<CheckBox
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Content="Is Lecturer?"
IsEnabled="False"
IsChecked="{Binding Path=IsLecturer}" />
</Grid>
</Border>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<StackPanel>
<ListBox
ItemsSource="{Binding}"
ItemTemplate="{StaticResource MyDataTemplate}" />
<Button
Content="Add"
Click="Button_Click" />
</StackPanel>
</phone:PhoneApplicationPage>
בדוגמא זו אנו מגדירים שכל אלמנט מסוג MyData יוצג ע"י Grid שבתוכו מספר פקדים (מסוג TextBlock ו CheckBox) שיציגו בצורה גרפית את התכונות החשובות של האלמנט.
בנוסף נשים לב לשימוש בתכונה ItemTemplate בפקד ListBox. תכונה זו מציינת באיזה Data Template יש להשתמש בשביל לצייר את האלמנטים ברשימה. בזמן ריצה עבור כל אלמנט שברשימה ייוצר עותק מהתוכן הגרפי של ה Data Template לצורך הצגת האלמנט. בנוסף, האלמנט עצמו (מסוג MyData) יקבע באופן אוטומטי להיות ה DataContext של הפקדים הגרפיים שב Data Template. באופן זה כאשר משתמשים ב Binding בהגדרת ה Data Template, האובייקט מקור יהיה באופן אוטומטי האלמנט שגרם ליצירת הפקדים הנ"ל.
תוצאת הרצת התוכנית באמצעות הקוד הנ"ל נראית כך:
תגובות בפייסבוק