Introduction
Once I had a task - create a report with a background that will not be printed. After a long and fruitless search for answers on the Internet, I began to solve the problem by myself - and want to share my solution.
Background
The main idea is that .NET ReportViewer
uses the same "mechanics" (rendering) to generate report (pre)view and to print report (and, I guess, to generate any exporting file). And where is no property for elements to define when it should be visible. But you can use an expression to set a number of properties - Hidden
or BackgroundImage.Source
, in my case, using report parameters. So if you know the reason next rendering will be executed for - you can set some parameters to values determining elements visibility, and report will be rendered the way you want.
Using the Code
I will describe only my case - to hide a page background when printing, but you can show|hide report elements in other cases the same way.
First, I added an image and a parameter to my report:
and make a report body background expression like:
=IIf(Parameters!HideBg.Value=True, "", "ReportBackground")
Second, I added two event handlers to ReportViewer
:
and in the code:
private void Form1_Load(object sender, EventArgs e)
{
this.rv.LocalReport.ReportEmbeddedResource = "RerportViewer.NonPrintableBg.Report1.rdlc";
this.rv.LocalReport.SetParameters(new Microsoft.Reporting.WinForms.ReportParameter("HideBg", "False", true));
this.rv.RefreshReport();
}
private bool printing = false;
private void rv_PrintingBegin(object sender, Microsoft.Reporting.WinForms.ReportPrintEventArgs e)
{
this.rv.LocalReport.SetParameters(new Microsoft.Reporting.WinForms.ReportParameter("HideBg", "True", true));
this.printing = true;
}
private void rv_RenderingComplete(object sender, Microsoft.Reporting.WinForms.RenderingCompleteEventArgs e)
{
if (this.printing == true)
{
this.printing = false;
this.rv.LocalReport.SetParameters(new Microsoft.Reporting.WinForms.ReportParameter("HideBg", "False", true));
}
}
By setting a parameter before the rendering will be called, you can manage how the report will be rendered. As the ReportViewer
has events on every button pressed (and for export too), you can define some variables and set them in event handlers, resetting after rendering is complete to restore the default (viewable) report state.
So, you can see the app:
and the printed report:
Works exactly the way I wanted it to.