只要用户通过单击加号展开行组,就可以通过自动滚动网页来相信它正在“有帮助”。骇客微软DLL,没有人知道一种方法来阻止这种行为?Reporting Services在展开时自动滚动到锚点
在网上搜索,我发现this years-old thread discussing the same issue,但没有答案。我希望我在SO的朋友可能会更有知识。
只要用户通过单击加号展开行组,就可以通过自动滚动网页来相信它正在“有帮助”。骇客微软DLL,没有人知道一种方法来阻止这种行为?Reporting Services在展开时自动滚动到锚点
在网上搜索,我发现this years-old thread discussing the same issue,但没有答案。我希望我在SO的朋友可能会更有知识。
我刚刚遇到同样的问题,并把一个肮脏的修复地方!我使用报告查看器控件在我自己的自定义ASP.Net页面中显示报告。这可以帮助我,因为我可以在我的外部主机页面中添加一些额外的脚本。以下是我所做的:
我在我的页面上打开了MaintainScrollPositionOnPostback
,因为我很懒,只是劫持他们的函数来计算滚动条的位置。
我设置了一个间隔来捕获滚动条Y位置每50ms。
我将事件处理程序附加到SSRS IFrame的加载事件,该事件处理程序会将滚动条设置回以前的位置。
当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>
的澄清溶液很简单,如果你知道如何做到这一点。 ;)
所有你需要做的就是将下面的代码是什么:
<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。 而我们正在这样做。瞧!
与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 */
}
只要overright中的ReportViewer JS天然ScrollToTarget功能到ReportViewerWebForm.aspx:
$(document).ready(function() {
Microsoft.Reporting.WebFormsClient._ReportArea.prototype.ScrollToTarget = function(){};
});
清洁和它适用于IE11和Chrome。适合我!应该标记为答案。 – 2018-01-16 18:05:56