2009-05-29 8 views
0

Reporting Services semble croire qu'il est «utile» de faire défiler automatiquement la page Web lorsqu'un utilisateur développe un groupe de lignes en cliquant sur le signe plus. À court de piratage d'une DLL Microsoft, quelqu'un sait-il un moyen d'arrêter ce comportement?Reporting Services défile automatiquement vers une ancre lors de l'expansion

Recherche autour du net, j'ai trouvé this years-old thread discussing the same issue, mais pas de réponse. J'espérais que mes amis à SO pourraient être un peu plus informés.

Répondre

1

Je viens de frapper le même problème et mettre une solution sale en place! Je montre des rapports dans ma propre page ASP.Net personnalisée en utilisant le contrôle de visionneuse de rapport. Cela m'aide parce que je peux mettre un script supplémentaire sur ma page hôte externe. Voici ce que j'ai fait:

J'ai allumé MaintainScrollPositionOnPostback sur ma page comme je suis paresseux et juste détourner leur fonction pour travailler sur la position des barres de défilement.

Je définis un intervalle pour capturer l'emplacement Y des barres de défilement toutes les 50 ms.

J'attache un gestionnaire d'événements à l'événement de chargement de l'IFrame SSRS qui remettra la barre de défilement à l'endroit où elle était auparavant.

Lorsque SSRS publie en arrière l'événement de chargement iframe se produit. À ce stade, SSRS a agacé la barre de défilement. Mon gestionnaire d'événements intervient et le remet en place! C'est assez dégueulasse mais fait le boulot.

code:

<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> 
0

La solution claire est assez simple, si vous savez comment le faire. ;)

Tout ce que vous avez à faire est d'ajouter le code suivant:

<script type="text/javascript" language="javascript"> 

    $(document).ready(function() { 
     $('.A0').get(0).ClientController.CustomOnReportLoaded = function() { 
      this.m_reportObject.m_navigationId = null; 
     }; 
    }); 

</script> 

où "A0" de $('.A0') est le nom de classe css attribué à un contrôle ReportViewer.

Pour référence, je suis méthode coller l'initialisation contrôle 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(); 
    } 

qui est invoqué par exemple ci-dessus comme:

InitializeReportViewer("A0"); 

Ci-dessous l'explication, pourquoi cela fonctionne:

contrôle ReportViewer génère beaucoup de code javascript, qui contient entre autres les suivants:

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(); 
} 

défilement Annoying est à cause de cette partie du code:

if (null != this.m_navigationId && this.m_navigationId != "") 
     window.location.replace("#" + this.m_navigationId); 

Nous avons donc besoin de mettre this.m_navigationId à null. Où?

Avant cette partie du code this.m_clientController.OnReportLoaded méthode est invoquée, et à la fin est l'invocation de la méthode CustomOnReportLoaded(), donc nous avons juste besoin de définir null pour m_navigationId dans cette méthode. Et nous le faisons. Voila!

0

Travaillé pour moi lors de l'utilisation avec le contrôle ReportViewer 10.0.30319.1. Pas très joli car il touche le _ReportArea qui est censé être privé et élimine la fonction ScrollToTarget du tout ce qui peut être nécessaire dans certains scénarios. Une autre méthode consiste à accéder à cette fonction et/ou à la propriété NavigationId de ReportPage en accédant aux contrôles, mais vous devez connaître l'ID exact du contrôle - dans mon cas, reportViewerDivId_ctl09, construit à partir de l'ID côté client de rsweb: Contrôle ReportViewer Asp.Net. Voir deuxième exemple

Exemple 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() { }; 
     } 
    } 
}); 

Exemple 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 */ 
} 
1

Juste overright native fonction ScrollToTarget du ReportViewer dans ReportViewerWebForm.aspx:

$(document).ready(function() { 
    Microsoft.Reporting.WebFormsClient._ReportArea.prototype.ScrollToTarget = function(){}; 
}); 
+0

propre et fonctionne dans IE11 et Chrome. Parfait pour moi! Devrait être marqué comme la réponse. –

Questions connexes