ReportViewer是一个需要viewstate的控件,MVC没有。要进行分页,您有两种选择,1. 将当前页面保留在会话中,并使用 ajax 保留当前页面。2.在页面上保留一个隐藏的iframe,使用jquery刷新,然后将页面替换为iframe的内容。这给人一种伪异步的感觉。
关于 #1 的注释,ReportViewer 在呈现报告(页面加载后)之前不会确定总页数,因此您最好的选择是在页面加载时获取它并告诉会话它是什么,以便您可以更好地浏览您的报告。
**
**
ReportViewerControl.ascx - 包含 ReportViewer 控件的部分视图。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NMBS.Models.SelectedReport>" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<rsweb:ReportViewer ID="ReportViewer" runat="server" Width="652px" AsyncRendering="false">
</rsweb:ReportViewer>
</form>
<script runat="server">
/* Prepare the ReportViewer Control to be Displayed */
private void Page_Load(object sender, System.EventArgs e)
{
// Set the PageCount Mode to Actual (Exact) instead of the Default (Approx.)
ReportViewer.PageCountMode = PageCountMode.Actual;
// Load Report Definition.
// Load DataSets.
// Etc...
ReportViewer.CurrentPage = Convert.ToInt32(Session["CurrentPage"]);
ReportViewer.LocalReport.Refresh();
}
</script>
ReportView.cshtml - 将显示 ReportViewer Partial 的 Razor 视图。
@* ReportViewer Control *@
<div id="div-report">
@* Load the Report Viewer *@
@Html.Partial("ReportViewerControl", this.ViewData.Model) <br />
</div>
@* Scripts *@
<script type="text/javascript" src="/Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/Scripts/Json2.js"></script>
<script type="text/javascript" src="/Scripts/ReportView-Scripts.js"></script>
ReportView-Scripts - 适当加载 ReportViewer 和导航的脚本。
// Since the ReportViewer Control determines the PageCount at render time, we must
// send back the Total Page Count for us to use later.
function SetTotalPages() {
var CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html();
// Send JSON to /Report/SetPageCount/.
// /Report/SetPageCount/ this action sets the variable Session["PageCount"] equal to the variable passed to it.
$.ajax({
url:"/Report/SetPageCount/",
type: "POST",
dataType: "json",
data: "{ Count:" + PageCount + "}",
cache: false,
contentType: 'application/json; charset=utf-8',
success: function (response, textStatus, jqXHR)
{ },
error: function (jqXHR, textStatus, errorThrown)
{ }
});
// When done, update the Information.
$("#txtNavigation").val(CurrentPage.toString() + " of " + PageCount.toString());
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
Nav.UpdateFunctionality();
}
var Nav = {
// If passed true, Enables First and Previous buttons.
// If passed false, Disables them.
ToggleFirstPrev: function ToggleFirstPrevNav(Toggle) {
var NavBar = $("#span-navigation");
if (Toggle == true) {
// Enable First and Previous.
NavBar.children("input[title=First]").removeAttr("disabled");
NavBar.children("input[title=Previous]").removeAttr("disabled");
} else {
// Disable First and Previous.
NavBar.children("input[title=First]").attr("disabled", true);
NavBar.children("input[title=Previous]").attr("disabled", true);
}
},
ToggleLastNext: function ToggleLastNextNav(Toggle) {
var NavBar = $("#span-navigation");
if (Toggle == true) {
// Enable First and Previous.
NavBar.children("input[title=Last]").removeAttr("disabled");
NavBar.children("input[title=Next]").removeAttr("disabled");
} else {
// Disable First and Previous.
NavBar.children("input[title=Last]").attr("disabled", true);
NavBar.children("input[title=Next]").attr("disabled", true);
}
},
UpdateFunctionality: function UpdateNavBarFunctionaility() {
var CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html(),
Navi = Nav;
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
if (parseInt(CurrentPage, 10) <= 1) {
Navi.ToggleFirstPrev(false);
} else {
Navi.ToggleFirstPrev(true);
}
// If the Report is already on the Last page, don't try navigating to Next or Last.
if (parseInt(CurrentPage, 10) >= parseInt(PageCount, 10)) {
Navi.ToggleLastNext(false);
} else {
Navi.ToggleLastNext(true);
}
}
};
// Makes an Ajax call telling the Action (NavReportControl) which navigation button was clicked.
// It then on the Server-Side updates the CurrentPage Counter to the New Page (based on Nav Button Clicked).
// On Success it Refreshes the Iframe. On Iframe Load it copies over the new ReportViewer Control.
// (Reason we do it this way is because without the IFrame we'd have to do it synchronously to get the
// ReportViewer Control to do it's Initialize Function).
function NavReport(e) {
// Gets what Navigation Action the user is trying to accomplish. (Next, Previous, First, Last) (and also Apply but that'll Change)
var Navi = { Nav: $(this).val() },
CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html();
// Get the New ReportViewer Control.
$.ajax({
type: "GET",
dataType: "json",
data: Navi,
cache: false,
contentType: 'application/json; charset=utf-8',
url: "/Report/NavReportControl",
success: function () {
RefreshiFrame();
}
});
}
**
**
// Refreshes the Iframe containing another instance of the ReportViewer Control.
function RefreshiFrame() {
// Hide the Report till update is finished.
$("#div-report").fadeOut(175);
// Refresh the Hidden Frame on the Page.
document.getElementById("iframe1").contentDocument.location.reload(true);
}
// This function is ran when the iFrame is finished loading.
// SrcName - Name of the Source iFrame. Ex. "#iframe1"
// DestName - Name of the Destination Div Ex. "#div-report"
function RefreshReport(SrcName, DestName) {
// Copy its "div-report" and CSS then replace it with the actual pages after reload.
var ReportViewer = $(SrcName).contents().find(DestName).html(),
CSS = $(SrcName).contents().find("head").children("[id*='ReportViewer']").clone(),
CurrentPage,
PageCount;
// Report Current ReportViewer with new ReportViewer.
$(DestName).html(ReportViewer);
//Add the New CSS to your current page.
$("head").append(CSS);
// Make sure the Report is visible.
$("#div-report").show();
// Update Nav Functionality.
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
Nav.UpdateFunctionality();
}