Tuesday, April 12, 2016

Crystal Reports woes

This took me an hour to figure out so I thought I'd write it down in case it helps anyone else.

If you have a form that's going to display a Crystal Report and you want to zoom it by default, the "normal" way would be to do this in form_Shown:

    private void ReportViewer_Shown(object sender, EventArgs e)
    {
        viewer.Zoom(2); // 1 = page width, 2 = whole page, 25..400 = zoom factor
    }

(Where viewer is the CrystalReportViewer component.)

Unfortunately, it takes CR a while to compute and display the actual report; by the time that happens, the .Zoom() call has already been executed (and ignored).

I have tried a number of workarounds (including launching a thread, waiting for two seconds and then calling the Zoom method - it worked but it was a horrible hack) before I discovered that CR has a "hidden" PageChanged event (it has a [Browsable(false)] attribute). Use that event by assigning a handler in the constructor:

    viewer.PageChanged += Viewer_PageChanged;

and then add the Viewer_PageChanged method:

    private void Viewer_PageChanged(object sender, EventArgs e)
    {
        viewer.Zoom(2);

        viewer.PageChanged -= Viewer_PageChanged;
    }

(Note that, in order to avoid leaking references, I have removed the PageChanged handler immediately after calling the Zoom method.)

No comments: