我想出了一个解决方法。由于 Crystal Reports 不允许覆盖按钮,因此我最终隐藏了打印按钮并使用 JavaScript/jQuery 添加了我自己的打印按钮。
以下是有关打印工作原理的一些幕后信息。当您按下打印按钮时,它会使用视图状态和事件参数进行回发。回发返回浏览器内联打开的 PDF 文件。 PDF 文件嵌入了一个打印命令,该命令在文件打开时执行。
所以我们可以做的是使用隐藏的 IFRAME 来加载可打印的 PDF。这样主页面不受影响。我认为 PDF 加载内联是导致页面/浏览器破坏其状态的原因。
将以下代码放在 ASPX 页面的顶部。你必须把它放在页面的顶部,否则如果你把它放在底部,打印对话框就会离开屏幕。
这是 HTML:
<iframe id="HiddenFrame" name="HiddenFrame" style="display: none;"></iframe>
<form id="PrintForm" action="MyPage.aspx" method="post" target="HiddenFrame">
<!-- Change the name if your object is not named 'CrystalReportViewer1' -->
<input type="hidden" name="__CRYSTALSTATECrystalReportViewer1" id="CRState" />
<input type="hidden" name="__VIEWSTATE" id="VState" />
<!-- Change this value to match your CrystalReportViewer object's name. -->
<input type="hidden" name="__EVENTTARGET" value="CrystalReportViewer1" />
<!-- This is the print command that is sent. -->
<input type="hidden" name="__EVENTARGUMENT" value='{"text":"PDF", "range":"false", "tb":"crpdfprint"}' />
</form>
如上所述,IFRAME 将加载我们的 PDF。该表单用于使用视图状态和事件参数对服务器进行 POST。 target 属性告诉表单加载到 IFRAME。
这里是 JavaScript:
// Hide the print button.
$('#CrystalReportViewer1_toptoolbar_print').hide();
// Inject our own print button. You can apply the same icon to your print button using CSS to make it look like the original icon.
$('#CrystalReportViewer1_toptoolbar_print').parent().append('<div id="PrintButtonOverride"></div>');
// When user clicks our print button, copy the states and submit the form.
$('#PrintButtonOverride').click(function () {
$('#CRState').val($('#__CRYSTALSTATECrystalReportViewer1').val());
$('#VState').val($('#__VIEWSTATE').val());
$('#PrintForm').submit();
});
点击事件从主页面复制两个视图状态,然后提交表单。我很快就写了这篇文章,如果我有不清楚的地方,我深表歉意。