How to access masterpage server controls from MVC controller in hybrid mode?
I'd like to be able to manipulate server controls in a masterpage template from a MVC Widget, instead of the typical 'from a usercontrol' scenario. Here's the code I have now, which gets me the controls on the page, but they only bring back controls that are in Placeholders, not controls that are on the masterpage itself. Is there anyway to access the controls on the masterpage from an MVC Controller?
Here's what I have so far in the MVC controller:
Guid currentPageId = SiteMapBase.GetCurrentNode().PageId;
PageManager pm = PageManager.GetManager();
PageData pageData = pm.GetPageData(currentPageId);
var masterTemplate = pageData.Template;
foreach
(var m
in
masterTemplate.Controls)
//currently cycles through controls in placeholders only.
<%@ Master Language=
"C#"
AutoEventWireup=
"true"
CodeBehind=
"MasterwithLayoutWidgets.master.cs"
Inherits=
"SitefinityWebApp.Content.Masters.MasterwithLayoutWidgets"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"Modernizr"
Src=
"/CommonControls/ModernizrInclude.ascx"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"JQuery"
Src=
"/CommonControls/JqueryInclude.ascx"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"KendoWeb"
Src=
"/CommonControls/KendoWebInclude.ascx"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"SiteStyles"
Src=
"/CommonControls/SiteStyles.ascx"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"PageHeader"
Src=
"/CommonControls/Header.ascx"
%>
<%@ Register TagPrefix=
"cc"
TagName=
"PageFooter"
Src=
"/CommonControls/Footer.ascx"
%>
<!DOCTYPE html>
<!--[
if
lt IE 7]> <html
class
=
"no-js lt-ie9 lt-ie8 lt-ie7"
> <![endif]-->
<!--[
if
IE 7]> <html
class
=
"no-js lt-ie9 lt-ie8"
> <![endif]-->
<!--[
if
IE 8]> <html
class
=
"no-js lt-ie9"
> <![endif]-->
<!--[
if
gt IE 8]><!--> <html
class
=
"no-js"
> <!--<![endif]-->
<head id=
"Head1"
runat=
"server"
>
<title></title>
<meta http-equiv=
"content-type"
content=
"text/html; charset=utf-8"
/>
<meta http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta name=
"viewport"
content=
"width=device-width"
/>
<link rel=
"apple-touch-icon-precomposed"
href=
"/Content/Images/apple-touch-icon-precomposed.png"
/>
<link rel=
"shortcut icon"
href=
"/favicon.ico"
type=
"image/x-icon"
/>
<cc:Modernizr ID=
"Modernizr1"
runat=
"server"
/>
<cc:SiteStyles ID=
"SiteStyles1"
runat=
"server"
/>
<cc:JQuery ID=
"JQuery1"
runat=
"server"
/>
<cc:KendoWeb ID=
"KendoWeb1"
runat=
"server"
/>
</head>
<body>
<form id=
"form1"
runat=
"server"
>
<div id=
"page"
>
<header id=
"mainHeader"
>
<cc:PageHeader id=
"PageHeader1"
runat=
"server"
></cc:PageHeader>
</header>
<asp:Panel ID=
"mainDiv"
runat=
"server"
>
<%--<div runat=
"server"
id=
"main"
role=
"main"
>--%>
<asp:ContentPlaceHolder ID=
"optionalTopHeroContentPlaceholder"
runat=
"server"
></asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID=
"optionalSubNavPlaceholder"
runat=
"server"
></asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID=
"optionalBreadCrumbsPlaceHolder"
runat=
"server"
></asp:ContentPlaceHolder>
<asp:contentplaceholder id=
"bodyPlaceholder"
runat=
"server"
/>
<%--<div id=
"content"
class
=
"content col-2"
>
<section
class
=
"col-primary"
>
<asp:contentplaceholder id=
"leftSidePlaceholder"
runat=
"server"
/>
</section>
<aside id=
"sidebar"
class
=
"col-right"
>
<asp:ContentPlaceHolder ID=
"rightsideCrossSellPlaceholder"
runat=
"server"
></asp:ContentPlaceHolder>
</aside>
</div>--%>
<%-- <div id=
"relatedContent"
class
=
"row"
>
<div id=
"featuredRelated"
class
=
"modules-h col-4"
>--%>
<asp:ContentPlaceHolder ID=
"optionalRelatedSectionPlaceholder"
runat=
"server"
></asp:ContentPlaceHolder>
<%-- </div>
</div>--%>
<%--</div>--%>
</asp:Panel>
<cc:PageFooter id=
"PageFooter1"
runat=
"server"
></cc:PageFooter>
</div>
</form>
<script type=
"text/javascript"
src=
"/Content/Scripts/plugins.js"
></script>
<script type=
"text/javascript"
src=
"/Content/Scripts/main.js"
></script>
<script type=
"text/javascript"
src=
"/Content/Scripts/global.js"
></script>
</body>
</html>
Hi,
In order to achieve your goal you could try to use the following approach:
Guid currentPageId = SiteMapBase.GetCurrentNode().PageId;
PageManager pm = PageManager.GetManager();
PageData pageData = pm.GetPageData(currentPageId);
var masterTemplate = pageData.Template;
foreach
(TemplateControl m
in
masterTemplate.Controls)
Control panelControl = FindMainDiv((Control)m,
"mainDiv"
);
if
(panelControl !=
null
)
Panel panel = panelControl
as
Panel;
//panel.Controls.Add();
//panel.Controls.Remove();
public
Control FindMainDiv(Control root,
string
ID)
foreach
(Control ctrl
in
root.Controls)
if
(ctrl.Parent !=
null
&& ctrl.ID==ID)
return
ctrl;
else
if
(ctrl.Parent !=
null
)
Control control= FindMainDiv(ctrl.Parent, ID);
if
(control !=
null
)
return
control;
return
null
;
Ok i've tried implementing this, however I'm having trouble on this line with casting the TemplateControl as a System.Web.UI.Control:
Control panelControl = FindMainDiv((Control)m, "mainDiv");
The error is 'Cannot convert type 'Telerik.Sitefinity.Pages.Model.TemplateControl' to 'System.Web.UI.Control'.
I'm assuming 'TemplateControl' is from 'Telerik.Sitefinity.Pages.Model.TemplateControl'
I'm also assuming FindMainDiv takes and returns a 'System.Web.UI.Control'. Are these assumptions right?
Hi,
Yes, in this case you may check this help article which describes how to add/remove controls from page.
Regards,
Andrey
Telerik
Specifically, I was just looking to add a class to the 'mainDiv' panel control from the MVC widget codebehind with something like this: 'mainDiv.Attributes.Add("style", myStyleshere);'
So if I understand you correctly, I have to programatically remove and then re-add the panel control for this to work?
Hello,
Would it be possible to use content placeholder control instead of asp Panel control? This is needed because we do not provide currently access to controls different than placeholder controls.
Regards,
Andrey
Telerik
Hi,
Does Sitefinity 7.1 version allow to reach controls inside ASP.Net master pages but outside content place holders?
Thanks in advance.
Regards
Jon Mikel