当用户通过单击加号展开行组时,Reporting Services似乎认为通过自动滚动网页来“有用”。如果没有黑客入侵Microsoft DLL,有没有人知道如何阻止这种行为?
在网上搜索,我找到了this years-old thread discussing the same issue,但没有回答。我希望我在SO的朋友可能会更加知识渊博。
答案 0 :(得分:1)
我刚刚遇到同样的问题,并进行了肮脏的修复!我正在使用报表查看器控件在我自己的自定义ASP.Net页面中显示报表。这有助于我,因为我可以在我的外部主页中添加一些额外的脚本。这是我做的:
我在我的页面上打开了MaintainScrollPositionOnPostback
因为我很懒,只是劫持了他们的功能来计算滚动条的位置。
我设置一个间隔来每50ms捕获一次滚动条Y位置。
我将一个事件处理程序附加到SSRS IFrame的load事件,它将滚动条设置回原来的位置。
当SSRS回发iframe加载事件时。此时SSRS已经烦恼地调整了滚动条。我的事件处理程序启动并将其放回原位!这很令人作呕,但是做到了。
代码:
<script language="javascript">
$(document).ready(function() {
$('iframe').load(function() {
resetScrollbar();
});
});
var lastGoodScrollY = 0;
var interval = window.setInterval(getScrollY, 50);
function getScrollY() {
lastGoodScrollY = WebForm_GetScrollY();
}
function resetScrollbar() {
window.scrollTo(0, lastGoodScrollY);
}
</script>
答案 1 :(得分:1)
直接将reportviewer js本地ScrollToTarget函数改为ReportViewerWebForm.aspx:
$(document).ready(function () {
Microsoft.Reporting.WebFormsClient._ReportArea.prototype.ScrollToTarget = function(){};
});
答案 2 :(得分:0)
如果您知道如何做,那么明确的解决方案非常简单。 ;)
您需要做的就是添加以下代码:
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('.A0').get(0).ClientController.CustomOnReportLoaded = function() {
this.m_reportObject.m_navigationId = null;
};
});
</script>
其中来自$('.A0')
的“A0”是分配给ReportViewer控件的css类名。
供参考我正在粘贴方法初始化ReportViewer控件:
protected void InitializeReportViewer(string ID)
{
string reportsPath = ConfigGetter.GetReportsPath();
string reportingServerUrl = ConfigGetter.GetReportingServerUrl();
Instance = new ReportViewer();
Instance.ID = ID;
Instance.CssClass += ID;
Instance.ProcessingMode = ProcessingMode.Remote;
Instance.ServerReport.ReportServerUrl = new Uri(reportingServerUrl);
Instance.ServerReport.ReportPath = reportsPath + Config.Filename;
Instance.Enabled = true;
Instance.InternalBorderStyle = BorderStyle.None;
Instance.EnableViewState = true;
if (Config.AutomaticSize)
{
Instance.AsyncRendering = false;
Instance.SizeToReportContent = true;
}
else
{
Instance.Width = Config.Width;
Instance.Height = Config.Height;
}
Instance.ShowParameterPrompts = false;
Instance.ShowToolBar = false;
SetParameters();
}
在以上示例中调用,如:
InitializeReportViewer("A0");
以下解释,为何有效:
ReportViewer控件会生成大量的javascript代码,其中包含以下内容:
function OnLoadReport(reloadDocMap)
{
this.m_clientController.OnReportLoaded(this, reloadDocMap);
if (null != this.m_navigationId && this.m_navigationId != "")
window.location.replace("#" + this.m_navigationId);
if (this.m_autoRefreshAction != null)
setTimeout(this.m_autoRefreshAction, this.m_autoRefreshInterval);
}
RSReport.prototype.OnLoadReport = OnLoadReport;
function OnReportLoaded(reportObject, reloadDocMap)
{
this.m_reportObject = reportObject;
this.CurrentPage = reportObject.m_pageNumber;
this.TotalPages = reportObject.m_totalPages;
this.m_searchStartPage = reportObject.m_searchStartPage;
// Update the client side page number so that it is available to the server object
// if it was changed asynchronously.
var clientCurrentPage = GetControl(this.m_clientCurrentPageID);
if (clientCurrentPage != null)
clientCurrentPage.value = this.CurrentPage;
// If there is a document map, display it
if (this.HasDocumentMap())
{
// This method is called each time the report loads. This happens
// for page navigations and report actions. For many of these cases,
// the doc map didn't change, so don't reload it.
if (reloadDocMap)
{
if (this.CanDisplayBuiltInDocMap() && this.m_docMapUrl != "")
{
var docMapReportFrame = frames[this.m_docMapReportFrameID];
docMapReportFrame.frames["docmap"].location.replace(this.m_docMapUrl);
}
this.CustomOnReloadDocMap();
}
if (this.m_docMapVisible && this.CanDisplayBuiltInDocMap())
this.SetDocMapVisibility(true);
}
this.CustomOnReportLoaded();
}
烦人的滚动是因为这部分代码:
if (null != this.m_navigationId && this.m_navigationId != "")
window.location.replace("#" + this.m_navigationId);
所以我们需要将this.m_navigationId
设置为null。
在哪里?
在调用代码this.m_clientController.OnReportLoaded
方法的这一部分之前,最后是方法CustomOnReportLoaded()
的调用,所以我们只需要在此方法中为m_navigationId
设置null。
我们正在这样做。瞧!
答案 3 :(得分:0)
使用ReportViewer控件10.0.30319.1时为我工作。它不是非常漂亮,因为它触及_ReportArea,它应该是私有的,并且在某些情况下可能需要消除ScrollToTarget函数。另一种方法是通过访问控件来访问ReportPage的此函数和\或NavigationId属性,但是您需要知道确切的控件ID - 在我的例子中它是reportViewerDivId_ctl09,它是根据rsweb的客户端ID构建的: ReportViewer Asp.Net控件。 见第二个例子
示例1:
$(window).load(function () {
if (Microsoft && Microsoft.Reporting && Microsoft.Reporting.WebFormsClient) {
var rpp = Microsoft.Reporting.WebFormsClient._ReportArea;
if (rpp && rpp.prototype) {
rpp.prototype.ScrollToTarget = function () { };
}
}
});
示例2:
/* DOESN'T WORK!*/
var rp = $get('reportViewerDivId_ctl09_ReportControl'); /* rp.control is ReportPage */
rp[0].control.NavigationId = null;
/*THE BELOW WORKED*/
var ra = $('#reportViewerDivId_ctl09'); /*ra[0].control is ReportArea*/
if (ra[0] && ra[0].control && ra[0].control.ScrollToTarget) {
ra[0].control.ScrollToTarget = function () { }; /*overriding the function so that anoying scroll on Sort doesn't happen */
}