Crystal 报告分页和可选参数的 Web 查看器问题

Crystal Reports Web Viewer Issue with Pagination and Optional Parameters

我已经搜索了几天,但无论我尝试过什么,我都 运行 遇到了一个问题。问题是我似乎遇到了完美风暴,我无法让所有 3 件事同时工作。

  1. 分页
  2. 可选参数
  3. 参数对话框提示

所以这第一种方法是我一直在使用的方法并且一切正常,除了它不会导航过去 2(而且我非常清楚为什么导航不起作用)

// ##################################################################################################################################################
// METHOD 1: Everything works correctly except you can't go past page 2
    protected void Page_Load(object sender, EventArgs e)
    {
        CrystalReportViewer1.ReportSource = Session["myReportDoc"] as CrystalDecisions.CrystalReports.Engine.ReportDocument;

        if (CrystalReportViewer1.ReportSource == null)
        {
            //Generate the Report Document 
            Handlers.ReportHandler myReportHandler = new Handlers.ReportHandler();
            CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument = myReportHandler.GenerateReport("AlarmStatusReport");
            Session["myReportDoc"] = myReportDocument;   //This is were we save it off for next time
            CrystalReportViewer1.ReportSource = myReportDocument;
        }
    }

所以知道常见的修复方法是不使用页面加载,而是使用 Page_Init。这修复了导航...直到我打开一个包含可选参数的报告。有了这些,每次我尝试导航到下一页时,参数框都会重新出现,而不是正常工作,现在至少需要填写我的可选参数中的一个。 (每个 "next Page" 将提示减少 1 个可选)。但是,因为我被迫更改参数,所以 "refreshes" 报告,我又回到了第 1 页。

    // ##################################################################################################################################################
    // METHOD 2: Works, but not for any report that has Optional Parameters. They become "Required" and keep popping up instead of navigating to the next page
    protected void Page_Init(object sender, EventArgs e)
    {
        CrystalReportViewer1.ReportSource = Session["myReportDoc"] as CrystalDecisions.CrystalReports.Engine.ReportDocument;

        if (CrystalReportViewer1.ReportSource == null)
        {
            //Generate the Report Document 
            Handlers.ReportHandler myReportHandler = new Handlers.ReportHandler();
            CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument = myReportHandler.GenerateReport("AlarmStatusReport");
            Session["myReportDoc"] = myReportDocument;   //This is were we save it off for next time
            CrystalReportViewer1.ReportSource = myReportDocument;
        }
    }

现在,我真的很兴奋,因为我有点聪明并通过捕获导航并自己跟踪页面来解决了这两个问题。现在一切正常!直到我进入参数对话框提示并且它完全被顶起。

    // ##################################################################################################################################################
    // METHOD 3: Everything works correctly except the Prompt Box doesn't Format correcly due to the addition of the added Event Handers
    protected void Page_Load(object sender, EventArgs e)
    {

        CrystalReportViewer1.ReportSource = Session["myReportDoc"] as CrystalDecisions.CrystalReports.Engine.ReportDocument;

        if (CrystalReportViewer1.ReportSource == null)
        {
            //Generate the Report Document 
            Handlers.ReportHandler myReportHandler = new Handlers.ReportHandler();
            CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument = myReportHandler.GenerateReport("AlarmStatusReport");
            Session["myReportDoc"] = myReportDocument;   //This is were we save it off for next time
            CrystalReportViewer1.ReportSource = myReportDocument;

            //Init our Manual Page Counter to 1
            HiddenFieldPageNumber.Value = "1";
        }

        CrystalReportViewer1.Navigate += CrystalReportViewer1_Navigate;     //Simply Adding this event, EVEN IF IT HAS NO CODE, Breaks the style and formating of the Parameter Prompt box.
        CrystalReportViewer1.PreRender += CrystalReportViewer1_PreRender;
    }

    private void CrystalReportViewer1_Navigate(object source, CrystalDecisions.Web.NavigateEventArgs e)
    {
        //This prevents this event from Incrementing the Page again when the PreRender Event 
        //below re-sets which page to show. 
        if (_SkipPageIncrement == true)
        {
            return;
        }

        //Whenever the Navigation is used, this Event fires. Here is the problem, there is nothing that actually tells 
        //us if the user clicked on Previous or Next (or GotoPage for that Matter). So we have to do some guessing here
        if (e.CurrentPageNumber == 1 && e.NewPageNumber == 2)
        {
            //If they pressed "NEXT" we will always get Current = 1 and New = 2 due to the Pagination starting over on the PostBack
            //So we INCREMENT our real Page Number Value.
            HiddenFieldPageNumber.Value = (Convert.ToInt32(HiddenFieldPageNumber.Value) + 1).ToString();
        }
        else if (e.CurrentPageNumber == 1 && e.NewPageNumber == 1)
        {
            //If they pressed "PREV" we will always get Current = 1 and New = 1 due to the Pagination starting over on the PostBack
            //So we DECREMENT our real Page Number Value.
            HiddenFieldPageNumber.Value = (Convert.ToInt32(HiddenFieldPageNumber.Value) - 1).ToString();
        }
    }

    private void CrystalReportViewer1_PreRender(object sender, EventArgs e)
    {
        //The Viewer has a method that allows us to set the page number. This PreRender Event is the only
        //Event I could find that works. It comes AFTER the Navigate, but before the reports is rendered.
        _SkipPageIncrement = true; //The ShowNthPage re-triggers the Navigation, so this prevents it from running again.
        CrystalReportViewer1.ShowNthPage(Convert.ToInt32(HiddenFieldPageNumber.Value));
    }

如上所述,在我添加 OnNavigation 事件的那一刻,即使我注释掉了里面的所有实际代码,我的提示框也会变成这样...

至此(我的页面为深色背景,你可以看到现在显示,加上 "OK" 按钮全部顶起。

我只是不明白为什么捕获导航事件会破坏提示框,即使事件没有触发(在第一次加载时)也是如此。

旁注:我使用的是 VS 2019 和 CR 13.0.3500.0

所以感谢像我这样更擅长CSS的队友的帮助,我已经解决了问题"good enough"。因此,对于任何想使用 LOAD 事件(或者必须喜欢我)但随后失去使用导航能力并想使用我的方法的人来说,Crystal 报告参数提示的创可贴是简单地覆盖他们在你 Site.css 中的样式...

/*---------------------- Custom CSS for Report Prompt Buttons ----------------------*/

.pePromptButton {
    padding-bottom:4.3px;
}

td.pePromptButton {
    display: inherit;
}
    img {
    vertical-align:top;
}