在WPF应用程序中显示PDF不工作 - WebBrowser或Adobe Control

时间:2011-05-13 14:17:47

标签: c# wpf xaml pdf

我需要在WPF应用程序中显示PDF。从我在网上做的所有阅读中,似乎在WPF应用程序中显示PDF的[仅]方法是通过Adobe的控件或WebBrowser控件。我试过使用Adobe的控件,但是,我一直无法添加Reader控件,因为由于某些原因我无法找到它作为我可以添加到我的工具箱中的东西(即使添加了所需的引用)。我正在运行Windows 7(64位),VS2010,.NET 4.0,并安装了Adobe Acrobat 7.0 Professional和Adobe Acrobat 9 Pro Extended,如果这与它有关。所以无论如何,我决定在WindowsFormsHost中托管的WebBrowser控件中尝试它。我的XAML就是这样:

<WindowsFormsHost x:Name="FormsHost" Visibility="Visible" Grid.Column="1" Margin="7,0,0,0">
<WF:WebBrowser x:Name="WebBrowser" Dock="Fill" IsWebBrowserContextMenuEnabled="False" ScriptErrorsSuppressed="True" WebBrowserShortcutsEnabled="False" Margin="7,0,0,0" />
</WindowsFormsHost>

然后在C#代码背后:

WebBrowser.Navigate(new System.Uri(FileName));

其中FileName ==我需要显示的.pdf文件的确切位置。但是,当我运行这个时,我看到的是WebBrowser所在的完全空白的白色区域。我也试过像这样设置.pdf文件:

WebBrowser.Url = new System.Uri(FileName);

我得到完全相同的东西。我知道PDF正在正确的位置创建,因为我可以手动浏览到它并打开它。

有没有人知道为什么这不起作用?或者可能为什么我似乎没有Reader控件作为选项?在这一点上,任何解决方案都没问题,他们似乎都没有工作!

谢谢!

4 个答案:

答案 0 :(得分:7)

这就是我做的......

MAIN WINDOW XAML

 <Window x:Class="PDFView.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="PDFView">
        <Grid>
            <WebBrowser x:Name="Browser" />
        </Grid>
    </Window>

主要窗口代码

using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Navigation;

namespace PDFView {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string hostUri = "http://localhost:8088/PsuedoWebHost/";

        private HttpListener _httpListener;

        public MainWindow() {
            InitializeComponent();

            this.Loaded += OnLoaded;
        }

        /// <summary>
        /// Loads the specified PDF in the WebBrowser control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="routedEventArgs"></param>
        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            // Get the PDF from the 'database'
            byte[] pdfBytes = GetPdfData();

            // Create a PDF server that serves the PDF to a browser
            CreatePdfServer(pdfBytes);

            // Cleanup after the browser finishes navigating
            Browser.Navigated += BrowserOnNavigated;
            Browser.Navigate(hostUri);
        }

        /// <summary>
        /// Retrieve a byte array from a 'database record'
        /// </summary>
        /// <returns></returns>
        private byte[] GetPdfData() {
            // TODO: Replace this code with data access code
            // TODO: Pick a file from the file system for this demo.
            string path = @"c:\Users\Me\Documents\MyPDFDocument.pdf"; 
            byte[] pdfBytes = File.ReadAllBytes(path);

            // Return the raw data
            return pdfBytes;
        }

        /// <summary>
        /// Creates an HTTP server that will return the PDF  
        /// </summary>
        /// <param name="pdfBytes"></param>
        private void CreatePdfServer(byte[] pdfBytes) {
            _httpListener = new HttpListener();
            _httpListener.Prefixes.Add(hostUri);
            _httpListener.Start();
            _httpListener.BeginGetContext((ar) => {
                                                  HttpListenerContext context = _httpListener.EndGetContext(ar);

                                                  // Obtain a response object.
                                                  HttpListenerResponse response = context.Response;
                                                  response.StatusCode = (int)HttpStatusCode.OK;
                                                  response.ContentType = "application/pdf";

                                                  // Construct a response.
                                                  if (pdfBytes != null) {
                                                      response.ContentLength64 = pdfBytes.Length;

                                                      // Get a response stream and write the PDF to it.
                                                      Stream oStream = response.OutputStream;
                                                      oStream.Write(pdfBytes, 0, pdfBytes.Length);
                                                      oStream.Flush();
                                                  }

                                                  response.Close();
                                              }, null);

        }

        /// <summary>
        /// Stops the http listener after the browser has finished loading the document
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="navigationEventArgs"></param>
        private void BrowserOnNavigated(object sender, NavigationEventArgs navigationEventArgs)
        {
            _httpListener.Stop();
            Browser.Navigated -= BrowserOnNavigated;
        }

    }
}

答案 1 :(得分:0)

我担心您使用WinForms PDF控件并将其托管在WPF应用程序中。它有点烦人,但不难做到。这是一篇文章和一些示例源代码:

http://hugeonion.com/2009/04/06/displaying-a-pdf-file-within-a-wpf-application/

答案 2 :(得分:0)

迟到的答案,但它可能会帮助其他人 我正在使用Windows 8.1 x64机器 我的任务是使用户能够在设备上查看PDF文档(使用Windows操作系统的平板电脑)。经过大量的研究,我无法找到任何可行的解决方案,或者我应该说使用WindowsFormsHost感觉很脏!

我所做的是使用像这样的WebBrowser控件:

<WebBrowser Source="pack://siteoforigin:,,,/path/to/your/file.html"/>

注意: pack://siteoforigin:是指应用程序运行时的位置。因此,请确保您的.html个文件设置为ContentCopy Always 既然已经设置了html,您现在需要下载或只复制并粘贴以下.js代码:

/*
PDFObject v1.2.20111123
https://github.com/pipwerks/PDFObject
Copyright (c) Philip Hutchison
MIT-style license: http://pipwerks.mit-license.org/
*/
/*jslint browser: true, sloppy: true, white: true, plusplus: true */
/*global ActiveXObject, window */
var PDFObject = function (obj) {

if (!obj || !obj.url) { return false; }

var pdfobjectversion = "1.2",
    //Set reasonable defaults
    id = obj.id || false,
    width = obj.width || "100%",
    height = obj.height || "100%",
    pdfOpenParams = obj.pdfOpenParams,
    url,
    pluginTypeFound,

    //declare functions
    createAXO,
    hasReaderActiveX,
    hasReader,
    hasGeneric,
    pluginFound,
    setCssForFullWindowPdf,
    buildQueryString,
    get,
    embed;


/* ----------------------------------------------------
   Supporting functions
   ---------------------------------------------------- */

createAXO = function (type) {
    var ax;
    try {
        ax = new ActiveXObject(type);
    } catch (e) {
        //ensure ax remains null
        ax = null;
    }
    return ax;
};

//Tests specifically for Adobe Reader (aka Acrobat) in Internet Explorer
hasReaderActiveX = function () {

    var axObj = null;

    if (window.ActiveXObject) {

        axObj = createAXO("AcroPDF.PDF");

        //If "AcroPDF.PDF" didn't work, try "PDF.PdfCtrl"
        if (!axObj) { axObj = createAXO("PDF.PdfCtrl"); }

        //If either "AcroPDF.PDF" or "PDF.PdfCtrl" are found, return true
        if (axObj !== null) { return true; }

    }

    //If you got to this point, there's no ActiveXObject for PDFs
    return false;

};



//Tests specifically for Adobe Reader (aka Adobe Acrobat) in non-IE browsers
hasReader = function () {

    var i,
        n = navigator.plugins,
        count = n.length,
        regx = /Adobe Reader|Adobe PDF|Acrobat/gi;

    for (i = 0; i < count; i++) {
        if (regx.test(n[i].name)) {
            return true;
        }
    }

    return false;

};


//Detects unbranded PDF support
hasGeneric = function () {
    var plugin = navigator.mimeTypes["application/pdf"];
    return (plugin && plugin.enabledPlugin);
};


//Determines what kind of PDF support is available: Adobe or generic
pluginFound = function () {

    var type = null;

    if (hasReader() || hasReaderActiveX()) {

        type = "Adobe";

    } else if (hasGeneric()) {

        type = "generic";

    }

    return type;

};


//If setting PDF to fill page, need to handle some CSS first
setCssForFullWindowPdf = function () {

    var html = document.getElementsByTagName("html"),
        html_style,
        body_style;

    if (!html) { return false; }

    html_style = html[0].style;
    body_style = document.body.style;

    html_style.height = "100%";
    html_style.overflow = "hidden";
    body_style.margin = "0";
    body_style.padding = "0";
    body_style.height = "100%";
    body_style.overflow = "hidden";

};


//Creating a querystring for using PDF Open parameters when embedding PDF
buildQueryString = function (pdfParams) {

    var string = "",
        prop;

    if (!pdfParams) { return string; }

    for (prop in pdfParams) {

        if (pdfParams.hasOwnProperty(prop)) {

            string += prop + "=";

            if (prop === "search") {

                string += encodeURI(pdfParams[prop]);

            } else {

                string += pdfParams[prop];

            }

            string += "&";

        }

    }

    //Remove last ampersand
    return string.slice(0, string.length - 1);

};


//Simple function for returning values from PDFObject
get = function (prop) {

    var value = null;

    switch (prop) {
        case "url": value = url; break;
        case "id": value = id; break;
        case "width": value = width; break;
        case "height": value = height; break;
        case "pdfOpenParams": value = pdfOpenParams; break;
        case "pluginTypeFound": value = pluginTypeFound; break;
        case "pdfobjectversion": value = pdfobjectversion; break;
    }

    return value;

};


/* ----------------------------------------------------
   PDF Embedding functions
   ---------------------------------------------------- */


embed = function (targetID) {

    if (!pluginTypeFound) { return false; }

    var targetNode = null;

    if (targetID) {

        //Allow users to pass an element OR an element's ID
        targetNode = (targetID.nodeType && targetID.nodeType === 1) ? targetID : document.getElementById(targetID);

        //Ensure target element is found in document before continuing
        if (!targetNode) { return false; }

    } else {

        targetNode = document.body;
        setCssForFullWindowPdf();
        width = "100%";
        height = "100%";

    }

    targetNode.innerHTML = '<object    data="' + url + '" type="application/pdf" width="' + width + '" height="' + height + '"></object>';

    return targetNode.getElementsByTagName("object")[0];

};

//The hash (#) prevents odd behavior in Windows
//Append optional Adobe params for opening document
url = encodeURI(obj.url) + "#" + buildQueryString(pdfOpenParams);
pluginTypeFound = pluginFound();

this.get = function (prop) { return get(prop); };
this.embed = function (id) { return embed(id); };
this.pdfobjectversion = pdfobjectversion;

return this;
};

gihub repository使用了哪个 现在,一旦完成设置,您现在需要安装Adobe Reader
您的html页面应如下所示(用于测试):

<!DOCTYPE html>
<!-- saved from url=(0016)http://localhost -->
<head>
<title></title>
<link rel="javascript" href="js/pdfObject.js" />
</head>
<body style="border: 0; margin: 0; padding: 0">
    <embed src="..\path\to\your\file.pdf" width="600px" height="500px" alt="pdf" pluginspage="http://www.adobe.com/products/acrobat/readstep2.html">
</body>

现在是棘手的部分。
您需要将此html页面显示在WebBrowser控件中,如果成功,系统将提示您安装Acrobat Reader的更新。
更新成功后,重新启动应用程序,您的文件现在应显示在您的页面上! 快乐的编码!

答案 3 :(得分:-1)

https://stackoverflow.com/a/14074771/5370609

此代码不适用于显示pdf内的pdf文件的链接。

我不知道为什么。 并且不要避免消息框下载文件而是显示pdf文件,