我剛剛開始嘗試使用Ghostscript.Net。我的目標是使GhostscriptViewer適應我的WPF MVVM模塊化環境,但我無法在XAML Image控件中顯示頁面。我懷疑我的問題在於我對Ghostscript.Net的認識不足,或者不瞭解如何將圖像參數綁定到圖像控件。WPF MVVM Ghostscript.NET Viewer的適配器不會顯示PDF頁面作爲ImageSource
在這個應用程序中,我使用Prism和UnityContainer。 PdfViewModel中的PdfPageImage屬性綁定到視圖XAML中的圖像控件。在_viewer_displaypage方法中進行的轉換爲PdfPageImage提供了System.Windows.Interop.InteropBitmap類型的對象。我在想,RaisePropertyChangedEvent方法會導致控件被ImageSource對象更新。
<Image x:Name="PdfDocumentImage" Grid.Column="1" Grid.Row="0"
Source="{Binding PdfPageImage}"
Height="100"
Width="100">
</Image>
public class PdfViewModel : ViewModelBase, IPdfViewModel
{
private readonly IBitmapToImageSourceConverter _imageSourceConverter;
private readonly GhostscriptViewer _ghostscriptViewer;
private readonly GhostscriptVersionInfo _gsVersion =
GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL |
GhostscriptLicense.AFPL, GhostscriptLicense.GPL);
private ImageSource _pdfPageImage;
public ImageSource PdfPageImage
{
get => _pdfPageImage;
set
{
if (value == _pdfPageImage) return;
_pdfPageImage = value;
RaisePropertyChangedEvent(nameof(PdfPageImage));
}
}
public PdfViewModel(IPdfView view,
IEventAggregator eventAggregator,
IBitmapToImageSourceConverter imageSourceConverter,
GhostscriptViewer ghostscriptViewer)
: base(view)
{
_ghostscriptViewer = ghostscriptViewer;
_imageSourceConverter = imageSourceConverter;
_ghostscriptViewer.DisplayPage += _viewer_DisplayPage;
eventAggregator.GetEvent<PdfDocumentOpenedEvent>().Subscribe(OpenPdfDocument, ThreadOption.UIThread);
}
private void _viewer_DisplayPage(object sender, GhostscriptViewerViewEventArgs e)
{
PdfPageImage = _imageSourceConverter.ImageSourceForBitmap(e.Image);
}
private void OpenPdfDocument(string path)
{
_ghostscriptViewer.Open(path, _gsVersion, false);
}
}
public class BitmapToImageSourceConverter : IBitmapToImageSourceConverter
{
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject);
public ImageSource ImageSourceForBitmap(Bitmap bmp)
{
var handle = bmp.GetHbitmap();
try
{
return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally { DeleteObject(handle); }
}
}