I am building a WPF wrapper to display PDFs using Acrobat (from this CodePlex project)
The Codeplex project supplies enough samples on performing basic functions on the PDF Viewer, but lacks the functionalities of the WPF MVVM pattern. My WPF wrapper must expose dependency properties to modify the behaviour of the Acrobat PDF Viewer using Binding in Xaml.
Normal binding to proprties such as Filename, PageNumber, etc. is fine, as I am doing the following:
Create the Dependency Property (Can be implemented relatively easy from the codeplex project)
public static readonly DependencyProperty PdfPathProperty = DependencyProperty.Register("PdfPath", typeof(string), typeof(PdfViewer), new UIPropertyMetadata(null, LoadPDF)); public string PdfPath { get { return (string)GetValue(PdfPathProperty); } set { SetValue(PdfPathProperty, value); } } private static void LoadPDF(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as PdfViewer; if (control == null) return; control.LoadFile(); } private void LoadFile() { _winFormPdfHost.LoadFile(PdfPath); }
Where you use the UserControl, bind to the Dependency Property:
<viewer:PdfViewer x:Name="viewer" PdfPath="{Binding FileName}" ShowToolbar="{Binding ShowToolbar, UpdateSourceTrigger=PropertyChanged}" PageNumber="{Binding PageNumber, UpdateSourceTrigger=PropertyChanged}"> </viewer:PdfViewer>
This is all working as expected. However, I need to somehow pass commands through to the Wrapper. For instance, I need to trigger an action/command such as 'GoToFirstPage', and this is where I am stuck.
I want to do something like the following:
<viewer:PdfViewer x:Name="viewer" PdfPath="{Binding FileName}"
ShowToolbar="{Binding ShowToolbar, UpdateSourceTrigger=PropertyChanged}"
PageNumber="{Binding PageNumber, UpdateSourceTrigger=PropertyChanged}"
FirstPageCommand="{Binding GoToFirstPageCommand}">
</viewer:PdfViewer>
However this approach wont work, because I don't want to implement the functionality of the command in the ViewModel. I just want to execute the function in the Wrapper.
I basically want to build a custom toolbar which will cater for the logic instead of using the toolbar that Acrobat offers, and I will need to be able to pass through, or trigger commands in the wrapper from the outside somehow.
Edit
I can accomplish this by ignoring MVVM, and only expose a public method from the Wrapper:
In the wrapper - Remove the Dependency Property for the Command, and only expose the function:
public void GoToFirstPage() { _winFormPdfHost.GoToFirstPage(); }
From the ViewModel, access the method through the UserControl
private ICommand _FirstPageCommand; public ICommand FirstPageCommand { get { if (_FirstPageCommand == null) { _FirstPageCommand = CreateCommand(GoToFirstPage); } return _FirstPageCommand; } } public void GoToFirstPage(object obj) { var viewer = obj as WPFPdfViewer.PdfViewer; viewer.GoToFirstPage(); }
with the wrapper as the command parameter:
<Button VerticalAlignment="Center" Content="First" Padding="10,5,10,5" Margin="5" Command="{Binding FirstPageCommand}" CommandParameter="{Binding ElementName=viewer}"/>