【问题标题】:Displaying a PDF in a WPF Application Not Working - WebBrowser or Adobe Control在 WPF 应用程序中显示 PDF 不工作 - WebBrowser 或 Adob​​e 控件
【发布时间】:2011-05-13 14:17:46
【问题描述】:

我需要在 WPF 应用程序中显示 PDF。从我在线阅读的所有内容来看,似乎 [唯一?] 在 WPF 应用程序中显示 PDF 的方法是通过 Adob​​e 的控件或 WebBrowser 控件。我尝试使用 Adob​​e 的控件,但是,我无法添加 Reader 控件,因为由于某种原因,我找不到它作为我可以添加到我的工具箱中的东西(即使添加了所需的参考)。我正在运行 Windows 7(64 位)、VS2010、.NET 4.0,并安装了 Adob​​e Acrobat 7.0 Professional 和 Adob​​e 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 控件作为选项?在这一点上,任何一种解决方案都可以,只是它们似乎都不起作用!

谢谢!

【问题讨论】:

  • 嗨,如果我没记错的话,你必须创建一个 winforms 用户控件,并在其中使用 adobe 的控件来查看 pdf。然后使用 标记将用户控件插入 xaml。
  • 问题是我无法看到 Adob​​e 控件,即使添加正确的 Acrobat 引用然后转到工具箱 -> 选择项目 -> COM 组件也是如此。 Reader 控件不存在,所以我不能在用户控件上使用它。我不知道为什么它没有显示为选项:(

标签: c# wpf xaml pdf


【解决方案1】:

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

主窗口 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;
        }

    }
}

【讨论】:

  • 很好,但你可能想解释一下你做了什么。例如这会从 pdf 中读取字节,然后使用 HttpListenerResponse 将字节流式传输到浏览器中
【解决方案2】:

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

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

【讨论】:

  • 我之前实际上已经关注过这个。正如他在引用的视频中解释的那样,当我将 Adob​​e 控件添加到我的工具箱时,我遇到了问题并且无法确定如何继续,使用的控件不是一个选项。我只有:“Acrobat 3D Office Insert”和“Adobe Acrobat 7.0 Browser Control”。是用于此目的的控件的那些“新”名称。在那篇文章中,他使用了我没有的“阅读器”控件...
  • 你试过那个“浏览器控制”吗?它看起来像你需要的。
  • 现在使用。尝试以与引用链接使用 Reader 控件相同的方式使用它会导致我遇到“跨线程操作”异常,说我从创建它的线程以外的线程访问了该控件...
【解决方案3】:

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

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

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

注意: pack://siteoforigin: 指的是应用程序运行时的位置。因此,请确保您的 .html 文件设置为 Content 和 Copy 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>

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

【讨论】:

    猜你喜欢
    • 2011-05-29
    • 2017-10-15
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多