Publié
lundi 13 avril 2009 23:10
par
Audrey
En regardant les controls fournis par le SDK de la table Surface je me suis aperçue qu'il n'y avait pas de control DocumentViewer pour visualiser des documents XPS.
Au premier abord, on peut se dire, mais à quoi ça sert de pouvoir voir des XPS sur la table Surface ? Le format XPS permet de pouvoir garder une qualité du document parfaite même à des niveaux de zoom élevés, et par exemple, lors d'une réunion autour de la table Surface un utilisateur veut pouvoir zoomer sur un document pour le montrer à toute les personnes réunies, il est plus agréable que les caractères ne se pixelisent pas 
Du coup, j'ai décidé de travailler sur l'élaboration d'un control SurfaceDocumentViewer permettant de visualiser des documents XPS sur la table Surface. Le problème réside dans le fait de le rendre utilisable pour des NUI (Natural User Interface), afin qu'il soit le plus intuitif et le plus maniable possible par l'utilisateur.
Si on regarde l'interface du control DocumentViewer on s'aperçoit qu'il va falloir retravailler dessus :

Les Scrollbars, les barres d'outils et de recherche devront être enlevées et remplacées car elles ne sont pas exploitables avec les événements Contact qui permettent d'intéragir avec la table Surface. Grâce à Blend, on va pouvoir créer un style pour ce control et retoucher les éléments listés précédement. Voici ce que ça donne côté XAML :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<Style x:Key="SurfaceDocumentViewerStyle" BasedOn="{x:Null}" TargetType="{x:Type DocumentViewer}"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="ContextMenu" Value="{DynamicResource {ComponentResourceKey ResourceId=PUIDocumentViewerContextMenu, TypeInTargetAssembly={x:Type System_Windows_Documents:PresentationUIStyleResources}}}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type DocumentViewer}"> <Border Focusable="False" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Grid Background="{TemplateBinding Background}" KeyboardNavigation.TabNavigation="Local"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ScrollViewer Focusable="{TemplateBinding Focusable}" IsTabStop="true" TabIndex="1" x:Name="PART_ContentHost" Grid.Column="0" Grid.Row="1" CanContentScroll="false" HorizontalScrollBarVisibility="Hidden"/> <DockPanel Grid.Row="1"> <FrameworkElement Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" DockPanel.Dock="Right"/> <Rectangle Visibility="Visible" VerticalAlignment="top" Height="10"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#66000000" Offset="0"/> <GradientStop Color="Transparent" Offset="1"/> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </DockPanel> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> |
Ensuite il faut ajouter quelques controls de type Surface afin de pouvoir manipuler le document. Dans cette première version, j'ai opté pour 2 SurfaceButton pour naviguer entre les pages, et un SurfaceSlider pour gérer le zoom sur le document. Voici ce que ça donne côté XAML et côté Design :
1 2 3 4 5 6 7 8 9 10 11 12 |
<Grid> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="*" /> <RowDefinition Height="30" /> <RowDefinition Height="30" /> </Grid.RowDefinitions> <DocumentViewer Grid.Row="1" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" x:Name="viewXpsDocument" Document="{Binding}" Zoom="{Binding Path=Value, ElementName=sliderZoom}" IsHitTestVisible="False" ShowPageBorders="True" Style="{DynamicResource SurfaceDocumentViewerStyle}" SizeChanged="viewXpsDocument_SizeChanged" /> <s:SurfaceSlider Grid.Row="2" x:Name="sliderZoom" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Maximum="500" /> <s:SurfaceButton x:Name="ButtonUp" Grid.Row="0" Click="ButtonUp_Click" Content="^" Margin="0,0,6,0" FontSize="14" FontWeight="Bold" Foreground="#FFFFFFFF" /> <s:SurfaceButton x:Name="ButtonNDown" Grid.Row="3" Click="ButtonNDown_Click" Content="v" FontWeight="Bold" FontSize="14" Background="#33A4B4BD" Foreground="#FFFFFFFF"/> </Grid> |

Et en utilisant ce control dans un ScatterView pour des ScatterViewItems, voici ce que ça donne :
1 2 3 4 5 6 7 8 9 |
<Grid Background="{StaticResource WindowBackground}" > <s:ScatterView Name="scatterView1" > <s:ScatterView.ItemTemplate> <DataTemplate> <uc:SurfaceDocumentViewer x:Name="documentView" /> </DataTemplate> </s:ScatterView.ItemTemplate> </s:ScatterView> </Grid> |
Et à l'exécution sur l'émulateur :

Ce control peut être exploitable en l'état mais il peut être largement amélioré, avec par exemple le défilement fluide des pages au doigt, zoom sur une partie spécifique du document, recherche dans le document, etc ... Tout cela, je l'espère, fera partie d'une prochaine version du control SurfaceDocumentViewer dans un prochain post ! 
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 :