[英]Visual studio 2015 community report viewer version 12 Error getting extra margin using c#
我正在使用 Visual Studio 2015 社区报告查看器版本 12 在我的 c# 项目中显示 rdlc 报告。 这是正常的 A4 页面报告
它适用于客户端 PC 上的 windows xp、vista、win 7,但是当在 Windows 10 64 位上安装相同的应用程序时,我面临如下问题
正如您在上图中所看到的,右侧和底部出现了不必要的边距,并且字体大小也减小了。 但是当我将报告导出为 PDF 时,生成的 PDF 没有问题,它与我设计的报告相同。
我试过什么:
打印类代码
public static class _cWainfoPrintReport
{
private static int m_currentPageIndex;
private static IList<Stream> m_streams;
public static Stream CreateStream(string name,
string fileNameExtension, Encoding encoding,
string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}
public static void _mExport(LocalReport report, bool print = true, double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
{
string deviceInfo =
@"<DeviceInfo> <OutputFormat>EMF</OutputFormat> <PageWidth>" + _pageWightInches + "in</PageWidth> <PageHeight>" + _pageHeightInches + "in</PageHeight> <MarginTop>" + _MarginTopInches + "in</MarginTop> <MarginLeft>" + _MarginLeftInches + "in</MarginLeft> <MarginRight>" + _MarginRightInches + "in</MarginRight> <MarginBottom>" + _MarginBottomInches + "in</MarginBottom> </DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream,
out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
if (print)
{
_mPrint(_pageWightInches, _pageHeightInches, _MarginTopInches, _MarginLeftInches, _MarginRightInches, _MarginBottomInches);
}
report.ReleaseSandboxAppDomain();
}
// Handler for PrintPageEvents
public static void _mPrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new
Metafile(m_streams[m_currentPageIndex]);
// Adjust rectangular area with printer margins.
Rectangle adjustedRect = new Rectangle(
ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
ev.PageBounds.Width,
ev.PageBounds.Height);
// Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect);
// Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
public static PaperSize CalculatePaperSize(double WidthInCentimeters, double HeightInCentimetres)
{
int Width = int.Parse((Math.Round((WidthInCentimeters * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
int Height = int.Parse((Math.Round((HeightInCentimetres * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
PaperSize NewSize = new PaperSize();
NewSize.RawKind = (int)PaperKind.Custom;
NewSize.Width = Width;
NewSize.Height = Height;
NewSize.PaperName = "Letter";
return NewSize;
}
public static void _mPrint(double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
{
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
PaperSize RequiredPaperSize = CalculatePaperSize(_pageWightInches * 2.54, _pageHeightInches * 2.54);
bool FoundMatchingPaperSize = false;
for (int index = 0; index < printDoc.PrinterSettings.PaperSizes.Count; index++)
{
if (printDoc.PrinterSettings.PaperSizes[index].Height == RequiredPaperSize.Height && printDoc.PrinterSettings.PaperSizes[index].Width == RequiredPaperSize.Width)
{
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
printDoc.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
FoundMatchingPaperSize = true;
break;
}
}
if (!printDoc.PrinterSettings.IsValid)
{
throw new Exception("Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(_mPrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
}
public static void _mPrintToPrinter(this LocalReport report)
{
_mExport(report);
}
public static void _mDisposePrint()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
stream.Close();
m_streams = null;
}
}
}
打印按钮上的代码
PrintViewer _PJobEntry = new PrintViewer();
DataTable dt = new DataSet1.MainTableDataTable();
dt.Rows.Add('vales for dataset');
_PJobEntry._RptView.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", dt));
_PJobEntry._RptView.LocalReport.ReportEmbeddedResource = "WAINFOBUSSOLN.Printing.RptSaleInvoice02.rdlc";
_PJobEntry._RptView.SetDisplayMode(DisplayMode.PrintLayout);
_cWainfoPrintReport._mExport(_PJobEntry._RptView.LocalReport, true, 8.27, 11.69, 0.25, 0.25, 0.28, 0.25);
但它的打印也与上述相同
相同的应用程序在我的装有 Windows 10 64 位的 PC 上运行,但在装有 Windows 10 64 位的客户端 PC 上部署后无法运行
在客户端 PC .Net 4.0 框架上,SQL Server 2008,安装了 Windows 10 64 位
如何解决。
我认为这个问题与安装的任何工具或仅 Windows 10 64 位没有任何关系,特别是在这方面。
相反,这是 jdweng 和 Reza Aghaei 提到的 DPI 问题。 更具体地说,是高 DPI 设备。
不确定您是否注意到了,但是您上传的图像具有不同的像素,而低像素的图像显示了报告的正确呈现。 这可以说支持由高 DPI 引起的缩放问题的观点。
现在,有很多关于此的文章、帖子和问题。 但是,最接近为受害者提供某种正确方向的是 Microsoft 支持门户上的那个,它似乎几乎没有为这种行为提供的可能解决方案(是的,复数)和变通方法(再次,复数)。
您可以在此处找到这篇文章: https : //support.microsoft.com/en-au/help/3025083/windows-scaling-issues-for-high-dpi-devices
我相信,我在下面引用的解决方法应该可以暂时帮助您。
更改应用程序属性
在资源管理器或开始菜单上,右键单击应用程序名称,选择属性,选择兼容性选项卡,然后选中禁用高 DPI 设置时的显示缩放复选框。
注意:在 Windows 10 版本 1703 和更高版本的 Windows 中,禁用高 DPI 设置时的显示缩放选项的文本更改为覆盖高 DPI 缩放行为,缩放执行者:应用程序。
您应该禁用 DPI 无感知并将您的应用程序设置为 DPI 感知 - 即使不是,以防止缩放。
在较新版本的 Windows 10 上,我找到了一个不同的解决方案:您可以让应用程序处于任何 DPI 感知状态,但可以在不同的 DPI 感知状态下打开特定窗口。
不幸的是,我仍在寻找 100% 工作的状态,但 2 个选项似乎是不错的选择。
改变 DPI 意识
if (WindowsVersion.WindowsIs10_1809OrNewer) // this you can get yourself, need to look at build number
{
// https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/DPIAwarenessPerWindow/client/DpiAwarenessContext.cpp
_prevHosting = WinAPI.SetThreadDpiHostingBehavior((IntPtr)WinAPI.DPI_HOSTING_BEHAVIOR.BEHAVIOR_MIXED);
_prevDPIContext = WinAPI.SetThreadDpiAwarenessContext((IntPtr)win10DPIAwareness); // WinAPI.ContextDPIAwareness.Context_UnawareGdiScaled);
}
然后你可以在这个线程中打开你的新对话框,这个对话框将包含 ReportViewer。
以后改回来
if (WindowsVersion.WindowsIs10_1809OrNewer)
{
WinAPI.SetThreadDpiAwarenessContext(_prevDPIContext);
WinAPI.SetThreadDpiHostingBehavior(_prevHosting);
}
帮手
public static bool WindowsIs10_1809OrNewer
{
get { return WindowsIs10OrNewer && Environment.OSVersion.Version.Build >= 17763; }
}
public static bool WindowsIs10OrNewer
{
get { return Environment.OSVersion.Version >= new Version(10, 0); }
}
public enum DPI_HOSTING_BEHAVIOR
{
BEHAVIOR_INVALID = -1,
BEHAVIOR_DEFAULT = 0,
BEHAVIOR_MIXED = 1
}
public enum ContextDPIAwareness
{
Context_Unaware = -1,
Context_SystemAware = -2,
Context_PerMonitorAware = -3,
Context_PerMonitorAwareV2 = -4,
Context_UnawareGdiScaled = -5,
}
您可以尝试 Context_UnawareGdiScaled - 它实际上正确缩放 ReportViewer - 通常 - 或 Context_PerMonitorAware 以禁用缩放。
我在 RDP 会话中遇到了问题,如果你没有,可能你对这些选项没问题。
此外,遗憾的是,这仅适用于较新的 Windows 10 版本。 由于这些更新不是可选的,可能大多数 Windows 10 用户都将使用新版本,而 Windows 8 不受欢迎且所有其他 Windows 版本都不支持,因此很多用户应该使用最新的 Windows 10 版本。
当然,还远非完美。
顺便说一句,对于旧版本的 Windows,我只是通过 SetProcessDpiAwareness 禁用缩放,在那里没有找到更好的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.