Introduction▲
Absent de la version 2, le contrôle SaveFileDialog est enfin présent dans Silverlight 3. Celui-ci permet de sauvegarder du contenu en local et ouvre la voie à de nouveaux scénarios (téléchargement de fichiers depuis un serveur, génération de rapports puis sauvegarde en local, etc.).
Découvrons comment fonctionne ce nouveau contrôle.
L'application de démonstration est disponible en ligne ici.
I. Enregistrement de données dans un fichier▲
Nous allons partir d'une interface extrêmement simple contenant une TextBox et deux boutons.
<UserControl
x
:
Class
=
"SilverlightSaveFileDialogDemo.MainPage"
xmlns
=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns
:
x
=
"http://schemas.microsoft.com/winfx/2006/xaml"
Width
=
"500"
Height
=
"300"
>
<Canvas
x
:
Name
=
"LayoutRoot"
Background
=
"White"
>
<TextBox
x
:
Name
=
"txtArea"
TextWrapping
=
"Wrap"
AcceptsReturn
=
"True"
/>
<Button
Click
=
"btnSave_Click"
Content
=
"Sauver le texte"
/>
<Button
Click
=
"btnSaveImage_Click"
Content
=
"Télécharger une image depuis le serveur"
/>
<TextBlock
x
:
Name
=
"txtErrors"
Foreground
=
"Red"
/>
<TextBlock
Text
=
"Entrez un texte :"
TextWrapping
=
"Wrap"
/>
</Canvas>
</UserControl>
Le premier bouton permettra de sauvegarder dans un fichier le texte saisi dans la TexBox. Un clic dessus appellera la méthode btnSave_Click qui va afficher la SaveFileDialog :
private
void
btnSave_Click
(
object
sender,
RoutedEventArgs e)
{
SaveFileDialog saveDialog =
new
SaveFileDialog
(
);
saveDialog.
DefaultExt =
".txt"
;
saveDialog.
Filter =
"Fichiers texte (.txt)|*.txt|Tous les fichiers|*.*"
;
saveDialog.
FilterIndex =
1
;
bool
?
open =
saveDialog.
ShowDialog
(
);
if
(
open.
HasValue &&
open.
Value)
{
try
{
using
(
Stream fs =
saveDialog.
OpenFile
(
))
{
byte
[]
info =
(
new
UTF8Encoding
(
true
)).
GetBytes
(
txtArea.
Text);
fs.
Write
(
info,
0
,
info.
Length);
}
}
catch
(
Exception ex)
{
txtErrors.
Text =
ex.
Message;
}
}
}
La propriété DefaultExt permet d'indiquer l'extension par défaut à ajouter au nom du fichier si l'utilisateur n'en saisit pas.
La propriété Filter spécifie les types de fichier et leur description pris en compte par la boite de dialogue.
La propriété FilterIndex indique l'index du filtre sélectionné par défaut. Attention, le premier filtre a un index égal à 1 et non à 0 !
La méthode ShowDialog affiche la fenêtre à l'écran. Un renvoie un Nullable<bool> qui vaut vrai si l'utilisateur clique sur le bouton « enregistrer » et faux s'il ferme ou clique sur le bouton « annuler » de la fenêtre.
La méthode OpenFile retourne un flux en écriture sur le fichier spécifié par l'utilisateur. Il nous est ainsi possible d'écrire dans le fichier via ce flux.
Voici le résultat en image :
En appuyant sur le bouton « Sauver le texte » la boite de dialogue vous demandant de sélectionner un nom et un emplacement pour le fichier s'ouvre :
Le fichier a bien été créé sur le bureau :
En ouvrant le fichier nous pouvons vérifier que l'enregistrement s'est effectué correctement :
II. Téléchargement d'un fichier▲
Un autre scénario maintenant possible est la possibilité de télécharger via l'application Silverlight un fichier se trouvant sur un serveur puis de le sauvegarder en local. Pour l'illustrer, nous allons télécharger une image puis l'enregistrer sur le poste de l'utilisateur.
La classe LoadFileRequest utilisée ici permet de télécharger un fichier donné. Une fois le téléchargement terminé l'évènement LoadFileRequestCompleted est levé.
private
SaveFileDialog _saveImageDialog;
private
void
btnSaveImage_Click
(
object
sender,
RoutedEventArgs e)
{
_saveImageDialog =
new
SaveFileDialog
(
);
_saveImageDialog.
DefaultExt =
".jpg"
;
_saveImageDialog.
Filter =
"Fichiers image (.jpg)|*.jpg|Tous les fichiers|*.*"
;
_saveImageDialog.
FilterIndex =
1
;
bool
?
open =
_saveImageDialog.
ShowDialog
(
);
if
(
open.
HasValue &&
open.
Value)
{
LoadFileRequest loadFileRequest =
new
LoadFileRequest
(
Config.
URL_REP_IMAGES +
"/Creek.jpg"
);
loadFileRequest.
LoadFileRequestCompleted +=
LoadFileRequestLoadFileRequestCompleted;
loadFileRequest.
Execute
(
);
}
}
Vous remarquerez que nous créons et affichons la SaveFileDialog avant de télécharger le fichier. Peut-être voudriez-vous d'abord télécharger le fichier puis afficher la boite de dialogue dans la fonction de callback LoadFileRequestLoadFileRequestCompleted. Cela n'est cependant pas possible dans notre exemple car le SaveFileDialog doit obligatoirement être créé suite à une action utilisateur (event handler suite au clic d'un bouton par exemple). La créer ailleurs, provoquerait la levée d'une exception.
Une fois le téléchargement terminé nous vérifions que nous avons bien récupéré le fichier puis l'enregistrons via le Stream créé par le SaveFileDialog.
void
LoadFileRequestLoadImageRequestCompleted
(
object
sender,
LoadImageRequestCompletedEventArgs e)
{
if
(
e.
Result ==
null
)
{
txtErrors.
Text =
"Pas de réponse de la requête !"
;
}
else
{
try
{
using
(
Stream fs =
_saveImageDialog.
OpenFile
(
))
{
int
length =
Convert.
ToInt32
(
e.
Result.
Length);
byte
[]
byteResult =
new
byte
[
length];
e.
Result.
Read
(
byteResult,
0
,
length);
fs.
Write
(
byteResult,
0
,
byteResult.
Length);
}
}
catch
(
Exception ex)
{
txtErrors.
Text =
ex.
Message;
}
}
}
Encore une fois, n'oubliez un try/catch afin de pallier une erreur survenant lors de la sauvegarde.
Sources▲
Téléchargez les sources de la solution donnée en exemple.
Liens▲
Remerciements▲
J'adresse ici tous mes remerciements à l'équipe de rédaction de "developpez.com" pour le temps qu'ils ont bien voulu passer à la correction et à l'amélioration de cet article.
Contact▲
Si vous constatez une erreur dans le tutorial, dans les sources, dans la programmation ou pour toutes informations, n'hésitez pas à me contacter par le forum.