[WPF] Un petit lecteur de XPS
Après une soirée à coder, voici ma première petite application WPF. En utilisant le control WPFControlBook que Mitsu avait développé (ici) j'ai créé un petit lecteur de fichiers XPS. Le document XPS est ouvert et on peut le lire en tournant les pages à la souris. Voici une capture d'écran pour illustrer un peu mieux c'est que j'ai essayé de faire :

Pour réaliser cela, il suffit simplement de déposer le control Book (WPFBookControl) dans la form pour pouvoir s'en servir.
Ensuite il restait à résoudre le problème du lecteur XPS, il existe un control DocumentViewer qui permet de lire un document XPS, mais je voulais pouvoir traiter chaque page séparement afin de pouvoir les associer au control Book. Pour cela, j'ai inclus un petit morceau de code trouvé sur le forum MSDN US (ici) qui permet de générer chaque page du fichier XPS en fichier BMP :
public void SaveXpsPageToBitmap(string xpsFileName)
{
XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read);
FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
int pageCount = docSeq.References[0].GetDocument(false).Pages.Count;
for (int pageNum = 0; pageNum < pageCount; pageNum++)
{
DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum);
BitmapImage bitmap = new BitmapImage();
RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)docPage.Size.Width,
(int)docPage.Size.Height,96,96,
System.Windows.Media.PixelFormats.Pbgra32);
renderTarget.Render(docPage.Visual);
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
FileStream pageOutStream = new FileStream(xpsFileName + ".Page" + pageNum + ".bmp", FileMode.Create, FileAccess.Write);
encoder.Save(pageOutStream);
pageOutStream.Close();
}
}
J'ai ensuite créé un user control UCBitmap qui permet d'afficher un Bitmap dans un control Image.
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Stream imageStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read);
BitmapImage myImageStream = new BitmapImage();
myImageStream.BeginInit();
myImageStream.StreamSource = imageStream;
myImageStream.EndInit();
imagePage.Source = myImageStream;
}
Et avec une boucle permettant de passer chaque page du document XPS, je récupère le fichier Bitmap généré plus tôt et je l'affiche dans une instance de mon user control UCBitmap que j'associe ensuite au control Book de ma form principale, tout cela lorsque l'application est chargée.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
object itemPage;
SaveXpsPageToBitmap(FileName);
for (int i = 0; i < pageCount; i++)
{
string source = FileName + ".Page" + i + ".bmp";
UCBitmap bt = new UCBitmap(source);
itemPage = (object)bt;
myBook.Items.Add(itemPage);
}
}
Et enfin lorsque l'application est lancée, le fichier XPS s'affiche et grâce à la souris, on peut facilement feuilleter ce document XPS

Ce code n'est pas spécialement optimisé, il est le fruit de mes recherches d'une soirée. Tous les commentaires sont les bienvenus 
Ces bouts de codes sont les prémices d'une application un peu plus compléte que je souhaite réaliser en WPF et qui fera l'objet de plusieurs posts d'ici quelques temps.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :