SQL Server Visual studio 2015 community report viewer version 12 Error getting extra margin using c#

qvtsj1bj  于 2023-08-02  发布在  C#
关注(0)|答案(3)|浏览(108)

I am using Visual studio 2015 community report viewer version 12 to show rdlc reports in my c# project. here is normal A4 page report

its works fine for windows xp, vista, win 7 on client PCs but when same application is installed on Windows 10 64 bit then I am facing problem like below

as you can see in above image there are unnecessary margins are coming from right and bottom side as well as font size also reduced. but when I export report to PDF then there is no problem in generated PDF its same as report which I designed.

What was I Tried :

  1. I Installed MICROSOFT® REPORT VIEWER 2015 RUNTIME from https://www.microsoft.com/en-us/download/details.aspx?id=45496
  2. Installed Microsoft® SQL Server® 2014 Feature Pack (System CLR Types For SQL Server 2014)
  3. tried to Export RDLC directly to Printer using below code

Code for Print Class

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;
            }
        }
    }

Code on Print Button

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);

but its also printing same as describe above

the same application is running on my PC with Windows 10 64 bit but not working after deployment on client PC having Windows 10 64bit

On Client PC .Net 4.0 framework, SQL Server 2008, Windows 10 64 bit installed

How to resolve it.

yizd12fk

yizd12fk1#

I don't believe this issue has anything to do with any of the tools installed or only Windows 10 64-bit in particular for that matter.

Rather, it's an issue with DPI as mentioned by jdweng & Reza Aghaei. More specifically, high-DPI devices.

Not sure if you have noticed, but both the images you have uploaded are of different pixels and the image with low pixel shows proper rendering of the report. This arguably supports the point of the scaling issue being caused due to High DPI.

Now, there are many articles, posts and questions on this. But the one that comes very close of providing some sort of right direction to the victims is the one on Microsoft Support Portal which seems to have few possible resolutions (yes, plural) and workarounds (again, plural) provided for this behavior.

You can find this article here: https://support.microsoft.com/en-au/help/3025083/windows-scaling-issues-for-high-dpi-devices

I believe, the workaround I am quoting below should help you for time-being.
Change application properties

In Explorer or on the Start menu, right-click the application name, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.

Note: In Windows 10 Version 1703 and later version of Windows, the text of the Disable display scaling on high DPI settings option is changed to Override high DPI scaling behavior, scaling performed by: Application.

tct7dpnv

tct7dpnv2#

You should disable the DPI unawareness and set your application to DPI aware - even though it is not, in order to prevent scaling.

On newer versions of Windows 10, I found a different solution: you can have your application in any DPI-awareness state, but have specific windows you open in different DPI-awareness states.

Unfortunately though, I am still looking for a state that is working 100% of the time, but 2 options seem to be good candidates.

Change DPI awareness

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);
            }

Then you can open your new dialog in this thread, this dialog would contain the ReportViewer.

change back later

if (WindowsVersion.WindowsIs10_1809OrNewer)
                    {
                        WinAPI.SetThreadDpiAwarenessContext(_prevDPIContext);
                        WinAPI.SetThreadDpiHostingBehavior(_prevHosting);
                    }

Helpers

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,
    }

You could try Context_UnawareGdiScaled - which actually scales ReportViewer correctly - often - or Context_PerMonitorAware to disable the scaling.

I had issues here in RDP sessions, if you do not have that, probably you are fine with those options.

Also, sadly, this only works in newer Windows 10 versions. Since those updates are not optional, probably most Windows 10 users will be on the new version, and with Windows 8 being unpopular and all other Windows versions out of support, a lot of users should be on a recent Windows 10 version.

Still far from perfect, of course.

BTW, for older versions of Windows, I just disable scaling via SetProcessDpiAwareness, did not find a better way there.

mwkjh3gx

mwkjh3gx3#

In windows display setting change scaling to 100% this will work enter image description here

相关问题