簡體   English   中英

Visual Studio 2015 社區報告查看器版本 12 使用 c# 獲取額外保證金時出錯

[英]Visual studio 2015 community report viewer version 12 Error getting extra margin using c#

我正在使用 Visual Studio 2015 社區報告查看器版本 12 在我的 c# 項目中顯示 rdlc 報告。 這是正常的 A4 頁面報告

Windows 7 上的正常圖像

它適用於客戶端 PC 上的 windows xp、vista、win 7,但是當在 Windows 10 64 位上安裝相同的應用程序時,我面臨如下問題

Windows 10 中的錯誤

正如您在上圖中所看到的,右側和底部出現了不必要的邊距,並且字體大小也減小了。 但是當我將報告導出為 PDF 時,生成的 PDF 沒有問題,它與我設計的報告相同。

我試過什么:

  1. 我從https://www.microsoft.com/en-us/download/details.aspx?id=45496安裝了 MICROSOFT® REPORT VIEWER 2015 RUNTIME
  2. 已安裝 Microsoft® SQL Server® 2014 Feature Pack(SQL Server 2014 的系統 CLR 類型)
  3. 嘗試使用以下代碼將 RDLC 直接導出到打印機

打印類代碼

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 引起的縮放問題的觀點。

高 DPI_Scaling_Issue

現在,有很多關於此的文章、帖子和問題。 但是,最接近為受害者提供某種正確方向的是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM