In last episode, we constructed a minimal ControlTemplate for SinglePageViewer. Although it did not expose any UI, it was fully functional in terms of keyboard shortcuts, selection, and layout. Now we’ll create a ControlTemplate with real UI. Here’s the markup (it’s long, but I’ll break out the important parts):
<SinglePageViewer xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
MinZoom="50" MaxZoom="200" FontFamily="Candara, Verdana">
<SinglePageViewer.Template>
<ControlTemplate TargetType="{x:Type SinglePageViewer}">
<AdornerDecorator>
<Grid>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<Border Grid.ColumnSpan="3" Margin="5,5,5,10" Padding="5"
BorderBrush="#aaa" BorderThickness="1,1,1,2"
Background="#fff">
<Border.BitmapEffect>
<DropShadowBitmapEffect />
</Border.BitmapEffect>
<DocumentPageView DocumentViewerBase.IsMasterPage="True"
PageNumber="0" />
</Border>
<TextBlock Grid.ColumnSpan="3" Margin="0,0,0,20"
VerticalAlignment="Bottom" HorizontalAlignment="Center"
Text="{Binding Path=MasterPageNumber, RelativeSource=/TemplatedParent}" />
<Slider Grid.Column="1" Grid.Row="1" Margin="5,5,10,5"
Value="{Binding Path=Zoom, RelativeSource=/TemplatedParent}"
Minimum="{Binding Path=MinZoom, RelativeSource=/TemplatedParent}"
Maximum="{Binding Path=MaxZoom, RelativeSource=/TemplatedParent}"
TickFrequency="{Binding Path=ZoomIncrement, RelativeSource=/TemplatedParent}" />
<Button Grid.Column="0" Grid.Row="1"
Command="PreviousPage"
IsEnabled="{Binding Path=CanGoToPreviousPage, RelativeSource=/TemplatedParent}">
Previous Page
</Button>
<Button Grid.Row="1" Grid.Column="2"
Command="NextPage"
IsEnabled="{Binding Path=CanGoToNextPage, RelativeSource=/TemplatedParent}">
Next Page
</Button>
</Grid>
</AdornerDecorator>
</ControlTemplate>
</SinglePageViewer.Template>
<FlowDocument>
<Paragraph FontSize="16">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Curabitur sodales, sem nec scelerisque aliquam, ipsum nibh
tristique nisl, eu dictum ipsum neque nec dolor. Nullam
magna lacus, mollis faucibus, auctor eget, placerat sit
amet, odio. Morbi feugiat, ligula tristique condimentum
luctus, eros nisi vestibulum ante, a porta dolor nibh sed
nisl. Cras a libero vitae leo eleifend tristique. Fusce
consequat, urna in consectetuer aliquet, felis purus luctus
nisl, at sollicitudin sem augue quis ante. Fusce convallis
nibh quis nisl. Fusce dictum faucibus velit. Proin tempus
orci a leo. Integer suscipit. Vestibulum nisl libero, congue
at, mollis sed, fringilla nec, lorem. Vestibulum ante ipsum
primis in faucibus orci luctus et ultrices posuere cubilia
Curae; Donec ac leo ut lectus tempus vestibulum. Proin vel
enim eget nisi rhoncus mollis. Duis dolor mauris, dictum
adipiscing, posuere nec, blandit et, orci.
</Paragraph>
</FlowDocument>
</SinglePageViewer>
Here are a couple of screenshots of the markup, the first is zoomed out to a small font size, the second has a large font size:


We’ve changed the structure of our ControlTemplate a bit, and added some new elements. Here’s a summary:
Border: In order ot make the content look like it’s on a physical page, we’ve wrapped the DocumentPageView with a Border element. Border is used to create a thin gray border and drop shadow (using DropShadowBitmapEffect) around the content.
TextBlock: This element displays the current page number. This is achieved by binding the Text property SinglePageViewer’s MasterPageNumber property.
Slider: The horizontal slider is bound to the Zoom property on SinglePageViewer.
Button: We’ve created two buttons, for “Previous Page” and “Next Page.” The Command property is set on the button, which hooks up the Button to fire the appropriate command when clicked. We’ve also bound the IsEnabled property to disable the buttons when appropriate (e.g. the “Previous Page” button is disabled if we’re displaying the first page).
Now we have a functional interface, but it’s not particularly pleasing to the eye. In part 3, we’ll create a more attractive look and feel.