Render Macro control on page load in umbraco template - asp.net

I am trying to load the razor script which exists as a separate macro in umbraco. I am using umbraco 4.7.0
I am basically doing geo-targeting and hence need to run the script each time on a page load. so I am looking for something like :
<script type="c#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Call the Macro here
}
Obviously I can do this in the template
<umbraco:Macro Alias="GeoTargetting" runat="server" />
but I need to call this macro before any control is loaded in the page.
PLease help.
Thanks

This appears to work alright:
Template:
<umbraco:Macro Alias="Sandbox" runat="server"></umbraco:Macro>
<asp:Label runat="server" ID="Label1" Text="Yo"></asp:Label>
Macro Script:
#using System.Web.UI.WebControls
#using umbraco.MacroEngines
#inherits DynamicNodeContext
#{
Page page = HttpContext.Current.Handler as Page;
page.Load += new EventHandler(page_Load);
}
#functions
{
static void page_Load(object sender, EventArgs e)
{
Page page = sender as Page;
Label label = FindControlRecursive(page, "Label1") as Label;
label.Text = "Hello";
}
private static Control FindControlRecursive(Control Root, string Id)
{
if (Root.ID == Id)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
}
Note: The FindControlRecursive() method is from this forum thread.

Related

List of controls in code behind

How can I add to a list<> some controls of my dashboard? I do something like List<String> NewList = new List<Strings>(){} but this throw me errors
I'm trying to add some linkButtons into the list.
I'm tying to do something like this but is wrong
protected void listLink(){
List<LinkButton> linksList = new List<LinkButton>();
listLink{
}
}
I want to use that list in other events
my linkbuttons are in visible = false;
From what i understand you want to create a list of LinkButtons using Object Initialization way.
Below code snippet should help you.
Aspx code:
<form id="form1" runat="server">
<asp:LinkButton ID="lnkBtn1" runat="server"></asp:LinkButton>
<asp:LinkButton ID="lnkBtn2" runat="server"></asp:LinkButton>
</form>
Aspx.cs code:
List<LinkButton> lnkBtnCollection = null;
protected void Page_Init(object sender, EventArgs e)
{
//Object Initialization way
lnkBtnCollection = new List<LinkButton>
{
lnkBtn1, lnkBtn2
};
//Second way where items are added to the list after the list is created
//lnkBtnCollection = new List<LinkButton>();
//lnkBtnCollection.Add(lnkBtn1);
//lnkBtnCollection.Add(lnkBtn2);
}
protected void Page_Load(object sender, EventArgs e)
{
//Use LinkBtn Collection here
foreach (var lnkBtn in lnkBtnCollection)
{
}
}

Set value to TextBox in UserControl inside placeholder

I have an textbox inside an user control. I created dinamically this user control and load in placeholder.
But when I tried to assign a value to the textbox, I raised next below error:
Object reference not set to an instance of an object
This is the user control:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="IVT_FormClient.ascx.cs" Inherits="Evi.Sc.Web.Evi.IVT.Sublayouts.IVT_FormClient" %>
<asp:Panel ID="pnlContainer" runat="server">
<asp:TextBox ID="txtClientNumber" runat="server"></asp:TextBox>
</asp:Panel>
The access modifier is (In the user control):
public string TxtFirstName
{
get { return txtFirstName.Text; }
set { txtFirstName.Text = value; }
}
In the web form I have the control reference:
<%# Reference Control="~/Evi/IVT/Sublayouts/IVT_FormClient.ascx" %>
In the code behind of the user control is:
public partial class frm_VerifyIdentity : System.Web.UI.Page
{
IVT_FormClient ivtFormClient = new IVT_FormClient();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
IVT_FormClient ivtFormClient = (IVT_FormClient)LoadControl("~/Evi/IVT/Sublayouts/IVT_FormClient.ascx");
Client UserClient = new Client();
UserClient = Load_ClientVerification(Server.HtmlEncode(Request.QueryString["ID"]).Trim());
if (UserClient != null)
{
ivtFormClient.TxtFirstName = UserClient.FirstName;
plhFormClient.Controls.Add(ivtFormClient);
}
}
}
}
The error occur is this line of code:
ivtFormClient.TxtFirstName = UserClient.FirstName;
Do not create an instance of a UserControl via constructor but with LoadControl as you have already done in Page_Load. However, you are doing that only if(!IsPostBack). Hence the control is instantiated the next postback via constructor.
Also, you have to recreate dynamic controls on every postback. I would suggest to add the UserControl delaratively to the page. You can hide/show it accordingly. Otherwise you need to create/add it always, best in Page_Init instead of Page_Load.
So this is not best-practise(just add it to the page) but should work as desired:
IVT_FormClient ivtFormClient = null;
protected void Page_Init(object sender, EventArgs e)
{
ivtFormClient =(IVT_FormClient)LoadControl("~/Evi/IVT/Sublayouts/IVT_FormClient.ascx");
Client UserClient = new Client();
UserClient = Load_ClientVerification(Server.HtmlEncode(Request.QueryString["ID"]).Trim());
if (UserClient != null)
{
ivtFormClient.TxtFirstName = UserClient.FirstName;
plhFormClient.Controls.Add(ivtFormClient);
}
}

how to access master page control from content page

I have a master page which contains a label for status messages. I need to set the status text from different .aspx pages. How can this be done from the content page?
public partial class Site : System.Web.UI.MasterPage
{
public string StatusNachricht
{
get
{
return lblStatus.Text;
}
set
{
lblStatus.Text = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
I have tried this, but was unsuccessful in making it work:
public partial class DatenAendern : System.Web.UI.Page
{
var master = Master as Site;
protected void Page_Load(object sender, EventArgs e)
{
if (master != null)
{
master.setStatusLabel("");
}
}
protected void grdBenutzer_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
//some code
if (master != null)
{
master.setStatusLabel("Passwort erfolgreich geändert.");
}
}
catch (Exception ex)
{
if (master != null)
{
master.setStatusLabel("Passwort konnte nicht geändert werden!");
}
}
}
}
}
In the MasterPage.cs file add the property of Label like this:
public string ErrorMessage
{
get
{
return lblMessage.Text;
}
set
{
lblMessage.Text = value;
}
}
On your aspx page, just below the Page Directive add this:
<%# Page Title="" Language="C#" MasterPageFile="Master Path Name"..... %>
<%# MasterType VirtualPath="Master Path Name" %> // Add this
And in your codebehind(aspx.cs) page you can then easily access the Label Property and set its text as required. Like this:
this.Master.ErrorMessage = "Your Error Message here";
In Content page you can access the label and set the text such as
Here 'lblStatus' is the your master page label ID
Label lblMasterStatus = (Label)Master.FindControl("lblStatus");
lblMasterStatus.Text = "Meaasage from content page";
It Works
To find master page controls on Child page
Label lbl_UserName = this.Master.FindControl("lbl_UserName") as Label;
lbl_UserName.Text = txtUsr.Text;
I have a helper method for this in my System.Web.UI.Page class
protected T FindControlFromMaster<T>(string name) where T : Control
{
MasterPage master = this.Master;
while (master != null)
{
T control = master.FindControl(name) as T;
if (control != null)
return control;
master = master.Master;
}
return null;
}
then you can access using below code.
Label lblStatus = FindControlFromMaster<Label>("lblStatus");
if(lblStatus!=null)
lblStatus.Text = "something";
You cannot use var in a field, only on local variables.
But even this won't work:
Site master = Master as Site;
Because you cannot use this in a field and Master as Site is the same as this.Master as Site. So just initialize the field from Page_Init when the page is fully initialized and you can use this:
Site master = null;
protected void Page_Init(object sender, EventArgs e)
{
master = this.Master as Site;
}
This is more complicated if you have a nested MasterPage. You need to first find the content control that contains the nested MasterPage, and then find the control on your nested MasterPage from that.
Crucial bit: Master.Master.
See here: http://forums.asp.net/t/1059255.aspx?Nested+master+pages+and+Master+FindControl
Example:
'Find the content control
Dim ct As ContentPlaceHolder = Me.Master.Master.FindControl("cphMain")
'now find controls inside that content
Dim lbtnSave As LinkButton = ct.FindControl("lbtnSave")
If you are trying to access an html element: this is an HTML Anchor...
My nav bar has items that are not list items (<li>) but rather html anchors (<a>)
See below: (This is the site master)
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="" runat="server" id="liHome">Home</a>
<a class="mdl-navigation__link" href="" runat="server" id="liDashboard">Dashboard</a>
</nav>
Now in your code behind for another page, for mine, it's the login page...
On PageLoad() define this:
HtmlAnchor lblMasterStatus = (HtmlAnchor)Master.FindControl("liHome");
lblMasterStatus.Visible =false;
HtmlAnchor lblMasterStatus1 = (HtmlAnchor)Master.FindControl("liDashboard");
lblMasterStatus1.Visible = false;
Now we have accessed the site masters controls, and have made them invisible on the login page.

How to dynamically set the Title of SiteMap from MasterPage?

In My Web.sitemap I have the following:
<siteMapNode url="~/Groups/ViewGroups.aspx" urlRoute="groups/{PostId}/{PostTitle}" />
</siteMapNode>
In my MasterPage I have implemented the ItemDataBound event to try and set the title of each page that implements the master page dynamically but for some reason the title is not being set.
protected void SiteMapPath1_ItemDataBound(object sender, SiteMapNodeItemEventArgs e)
{
string CurrentNodeTitle = GetTitleFromDatabase();
if (e.Item.ItemType == SiteMapNodeItemType.Current) {
e.Item.SiteMapNode.Title = CurrentNodeTitle;
}
}
I also tried this in the ItemCreated event but still it did NOT work.
If I set the title in the Web.sitemap then it works perfectly but when I set it using e.Item.SiteMapNode.Title = CurrentNodeTitle; the title is nto being set.
Try this.
private string currentKey = SiteMap.CurrentNode.Key
protected void SiteMapPath1_ItemDataBound(object sender, MenuEventArgs e)
{
string CurrentNodeTitle = GetTitleFromDatabase();
if (e.Item.DataPath == currentKey){
e.Item.Text = CurrentNodeTitle;
}
}
Edit note:
it should be MenuEventArgs
This question is about 6 years old now, and the one answer is completely wrong and should probably be deleted. I had a hard time finding the answer - it's not nearly as straight forward as I would have expected it to be, but the answer is pretty simple nonetheless.
Using the static SiteMap classes SiteMapResolve event from the System.Web namespace (NOT your instance of SiteMapPath!) you can manipulate the URL and Title on the fly.
In my case, I have a custom localization method that retrieves the localized strings from a database. The sitemap title's contain the key used to identify the string. This is the code behind for my Master Page:
protected void Page_Load(object sender, EventArgs e)
{
// ...
SiteMap.SiteMapResolve += (o, args) =>
{
if (SiteMap.CurrentNode == null)
return null;
SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
currentNode.Title = SessionObject.LocalizeText(currentNode.Title);
SiteMapNode tempNode = currentNode;
while (tempNode.ParentNode != null)
{
tempNode = tempNode.ParentNode;
tempNode.Title = SessionObject.LocalizeText(tempNode.Title);
}
return currentNode;
};
// ...
}
Then in your Master Page ASPX (or presumably any ASPX page that utilizes this Master Page), you can add <asp:SiteMapPath runat="server" ... /> and it should be processed by the SiteMapResolve event.

ASP CompositeControl & ScriptManager

I'm really new to the WebControl / CompositeControl world, and I have a small test class I am playing with. It's just a LinkButton that updates when clicked. Things work great when I leave it out of UpdatePanel. But when I try to run it inside I still get a full page POST response. How can I make this class work inside a UpdatePanel?
Here's the class:
public class Test2 : CompositeControl
{
private static readonly object testButtonEvent = new object();
public event EventHandler OnTestClick
{
add { Events.AddHandler(testButtonEvent, value); }
remove { Events.RemoveHandler(testButtonEvent, value); }
}
private LinkButton testLinkButton;
public virtual string testLinkButtonText
{
get
{
object o = ViewState["testLinkButtonText"];
return (o == null) ? String.Empty : (string)o;
}
set
{
if (value == null)
ViewState.Remove("testLinkButtonText");
else
ViewState["testLinkButtonText"] = value;
}
}
protected override void OnInit(EventArgs e)
{
/* This stuff makes it ajax friendly but stops the text rendering
EnsureChildControls();
ScriptManager ScMan = ScriptManager.GetCurrent(Page);
if (ScMan != null)
{
ScMan.RegisterAsyncPostBackControl(testLinkButton);
} */
base.OnInit(e);
}
protected override void CreateChildControls()
{
Controls.Clear();
testLinkButton = new LinkButton();
testLinkButton.Command += new CommandEventHandler(testClick);
testLinkButtonText = "Test ViewState Text";
Controls.Add(testLinkButton);
}
void testClick(object sender, CommandEventArgs e)
{
testLinkButtonText = "Updated Text On " + DateTime.Now.ToLongTimeString();
}
protected override void Render(HtmlTextWriter writer)
{
RenderContents(writer);
}
protected override void RenderContents(HtmlTextWriter writer)
{
EnsureChildControls();
testLinkButton.Text = testLinkButtonText;
testLinkButton.RenderControl(writer);
}
}
The code in OnInit() causes the control to post correctly, but I don't get the updated text for the LinkButton. It is still firing off the event - when I debug I can see it being called. What's the proper way to set this control up for use in a UpdatePanel?
Usage, just in case:
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<cc:Test2 ID="jqTest02" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
You have to give the button an ID property...this is used in the client-side javascript that drives the UpdatePanel. More specifically, it's listed in the list of controls to intercept and do async postbacks for.
testLinkButton.ID = "btn";

Resources