1. Silverlight Control Toolkit▲
1-1. Présentation▲
1-2. Installation▲
1-3. Préparation de l'article▲
Tout au long de cet article, nous allons utiliser 2 classes, Town et Neighborhood, afin de réaliser divers scénarios selon les contrôles.
public
class
Neighborhood
{
public
string
Name {
get
;
set
;
}
public
int
Rate {
get
;
set
;
}
}
public
class
Town
{
public
string
Name {
get
;
set
;
}
public
int
Rate {
get
;
set
;
}
public
List<
Neighborhood>
Neighborhoods {
get
;
set
;
}
public
override
string
ToString
(
)
{
return
this
.
Name;
}
}
List<
Town>
towns =
new
List<
Town>
{
new
Town
{
Name =
"San Francisco"
,
Rate =
5
,
Neighborhoods =
new
List<
Neighborhood>
{
new
Neighborhood {
Name =
"Union Square"
,
Rate =
5
},
new
Neighborhood {
Name =
"Pacific Heights"
,
Rate =
5
},
new
Neighborhood {
Name =
"Mission District"
,
Rate =
-
1
},
new
Neighborhood {
Name =
"North Beach"
,
Rate =
4
},
new
Neighborhood {
Name =
"Tenderloin"
,
Rate =
1
}
}
},
new
Town
{
Name =
"New York"
,
Rate =
-
1
,
Neighborhoods =
new
List<
Neighborhood>
{
new
Neighborhood {
Name =
"Harlem"
},
new
Neighborhood {
Name =
"Liberty Island"
},
new
Neighborhood {
Name =
"Civic Center"
},
new
Neighborhood {
Name =
"Queens"
},
new
Neighborhood {
Name =
"Manhattan"
}
}
},
new
Town {
Name =
"Berkeley"
,
Rate =
4
},
new
Town {
Name =
"Oakland"
,
Rate =
-
1
},
new
Town {
Name =
"San Jose"
,
Rate =
-
1
},
new
Town {
Name =
"Seattle"
,
Rate =
-
1
}
};
Nous allons également utiliser un Converter pour nos scénarios de DataBinding.
public
class
Rate2ImageConverter :
IValueConverter
{
#region IValueConverter Members
public
object
Convert
(
object
value
,
Type targetType,
object
parameter,
System.
Globalization.
CultureInfo culture)
{
if
(
value
is
int
)
{
int
rate =
(
int
)value
;
if
(
rate ==
-
1
) return
null
;
else
return
new
BitmapImage
(
new
Uri
(
string
.
Format
(
"Images/star{0}.png"
,
rate),
UriKind.
Relative));
}
return
null
;
}
public
object
ConvertBack
(
object
value
,
Type targetType,
object
parameter,
System.
Globalization.
CultureInfo culture)
{
throw
new
NotImplementedException
(
);
}
#endregion
}
Ce Converter permet de convertir un int en BitmapImage. On s'en servira pour afficher une image selon la notation (Rate) d'une ville ou d'un quartier.
2. Les contrôles▲
2-1. Le TreeView▲
2-1-1. Les bases▲
Première nouveauté dans ce pack de contrôles : le TreeView.
Rien de bien compliqué pour arriver à ce résultat :
<
control
:
TreeView
x
:
Name
=
"tvTowns"
>
<
control
:
TreeViewItem
Header
=
"San Francisco"
>
<
control
:
TreeViewItem
Header
=
"Union Square"
/>
<
control
:
TreeViewItem
Header
=
"Pacific Heights"
/>
<
control
:
TreeViewItem
Header
=
"Mission District"
/>
<
control
:
TreeViewItem
Header
=
"North Beach"
/>
<
control
:
TreeViewItem
Header
=
"Tenderloin"
/>
</
control
:
TreeViewItem>
<
control
:
TreeViewItem
Header
=
"New-York"
>
<
control
:
TreeViewItem
Header
=
"Harlem"
/>
<
control
:
TreeViewItem
Header
=
"Liberty Island"
/>
<
control
:
TreeViewItem
Header
=
"Civic Center"
/>
<
control
:
TreeViewItem
Header
=
"Queens"
/>
<
control
:
TreeViewItem
Header
=
"Manhattan"
/>
</
control
:
TreeViewItem>
</
control
:
TreeView>
Il s'agit ni plus ni moins que d'une suite de TreeViewItem imbriqués.
On peut également arriver à ce résultat en code-behind.
TreeViewItem sf =
new
TreeViewItem
(
);
sf.
Header =
"San Francisco"
;
sf.
Items.
Add
(
"Union Square"
);
sf.
Items.
Add
(
"Pacific Heights"
);
sf.
Items.
Add
(
"Mission District"
);
sf.
Items.
Add
(
"North Beach"
);
sf.
Items.
Add
(
"Tenderloin"
);
TreeViewItem ny =
new
TreeViewItem
(
);
ny.
Header =
"New-York"
;
ny.
Items.
Add
(
"Harlem"
);
ny.
Items.
Add
(
"Liberty Island"
);
ny.
Items.
Add
(
"Civic Center"
);
ny.
Items.
Add
(
"Queens"
);
ny.
Items.
Add
(
"Manhattan"
);
tvTowns.
Items.
Add
(
sf);
tvTowns.
Items.
Add
(
ny);
Voyons maintenant comment remplir notre TreeView via du DataBinding.
2-1-2. Le DataBinding▲
Nous allons utiliser la liste de Town précédemment créée dans la partie 1-3.
On pourrait tout d'abord penser qu'il faille faire comme pour tous les autres contrôles, mais ici il faut prendre en compte l'imbrication des éléments, et c'est là qu'un nouveau DataTemplate intervient : HierarchicalDataTemplate
Ce DataTemplate est utilisé pour afficher des éléments sous forme hiérarchique (ce qui est le cas pour un TreeView). Les éléments à afficher doivent obligatoirement avoir une collection d'enfants (Neighborhoods pour le cas de notre classe Town).
<
control
:
TreeView
x
:
Name
=
"tvTowns"
>
<
control
:
TreeView.ItemTemplate>
<
control
:
HierarchicalDataTemplate
ItemsSource
=
"{Binding Neighborhoods}"
>
<StackPanel
Orientation
=
"Horizontal"
>
<TextBlock
Text
=
"{Binding Name}"
/>
<Image
Source
=
"{Binding Rate, Converter={StaticResource Rate2Image}}"
Margin
=
"10,0,0,0"
/>
</StackPanel>
</
control
:
HierarchicalDataTemplate>
</
control
:
TreeView.ItemTemplate>
</
control
:
TreeView>
Une nouvelle propriété apparait dans le HierarchicalDataTemplate : ItemsSource. Il s'agit ni plus ni moins que du nom de la propriété contenant les éléments fils.
On affecte notre liste à notre TreeView et voici le résultat :
2-1-3. Les problèmes connus▲
Voici une liste non exhaustive des problèmes connus avec le TreeView. Ils seront normalement corrigés dans la prochaine release.
- DisplayMemberPath ne fonctionne pas
- On ne peut pas imbriquer les HierarchicalDataTemplate.
- Utiliser à la fois ItemStyle et ItemTemplate empêche la visualisation dans Blend
Vous trouverez surement d'autre Issues sur le site officiel : http://www.codeplex.com/Silverlight/WorkItem/List.aspx
2-2. L'AutoCompleteBox▲
2-2-1. Les bases▲
L'AutoCompleteBox est une TextBox proposant des suggestions selon ce que l'utilisateur tape.
Pour arriver à ce résultat, c'est très simple. Un ajoute tout d'abord notre contrôle dans notre XAML.
<
control
:
AutoCompleteBox
x
:
Name
=
"acTowns"
/>
On ajoute ensuite les suggestions.
acTowns.
ItemsSource =
new
string
[]
{
"San Francisco"
,
"New-York"
,
"Berkeley"
,
"Oakland"
,
"San Jose"
,
"Seattle"
};
Et on obtient le résultat montré plus haut.
Voyons à présent les différentes possibilités proposées :
Maintenant il serait intéréssant d'ajouter les suggestions au fur et à mesure par rapport à ce que tape l'utilisateur mais aussi agrémenter l'affichage.
2-2-2. Le DataBinding▲
On va tout d'abord agrémenter l'affichage. On reprend notre liste de Town, et on va afficher une image selon la notation.
<
control
:
AutoCompleteBox
x
:
Name
=
"acTowns"
>
<
control
:
AutoCompleteBox.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation
=
"Horizontal"
>
<TextBlock
Text
=
"{Binding Name}"
/>
<Image
Source
=
"{Binding Rate, Converter={StaticResource Rate2Image}}"
Margin
=
"10,0,0,0"
/>
</StackPanel>
</DataTemplate>
</
control
:
AutoCompleteBox.ItemTemplate>
</
control
:
AutoCompleteBox>
Voyons maintenant comment binder nos suggestions sur un WebService, selon ce que l'utilisateur tape. Pour cela nous allons utiliser le service de suggestions de Live.com.
On modifie légèrement le XAML.
<
control
:
AutoCompleteBox
x
:
Name
=
"acSearch"
Populating
=
"acSearch_Populating"
/>
On s'abonne simplement à l'évènement Populating qui est appelé chaque fois que quelque chose est tapé dans l'AutoCompleteBox.
private
void
acSearch_Populating
(
object
sender,
PopulatingEventArgs e)
{
AutoCompleteBox box =
sender as
AutoCompleteBox;
WebClient client =
new
WebClient
(
);
client.
DownloadStringCompleted +=
new
DownloadStringCompletedEventHandler
(
client_DownloadStringCompleted);
client.
DownloadStringAsync
(
new
Uri
(
"http://api.search.live.net/qson.aspx?query="
+
box.
Text));
}
void
client_DownloadStringCompleted
(
object
sender,
DownloadStringCompletedEventArgs e)
{
if
(
e.
Error ==
null
)
{
try
{
List<
string
>
suggests =
new
List<
string
>(
);
JsonObject jso =
((
JsonObject)JsonObject.
Parse
(
e.
Result))[
"SearchSuggestion"
]
as
JsonObject;
foreach
(
JsonObject suggest in
(
JsonArray)jso[
"Section"
]
)
{
suggests.
Add
(
suggest.
Values.
First
(
));
}
acSearch.
ItemsSource =
suggests;
acSearch.
PopulateComplete
(
);
}
catch
{
}
}
}
Une fois les suggestions récupérées à partir du service Live, nous les affectons à notre AutoCompleteBox, rien de plus compliqué.