How to dynamically set the Title of SiteMap from MasterPage? - asp.net

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.

Related

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.

value of private variable is not maintained after page load even in ASP.NET

I have two pages. first.aspx and second.aspx. In order to get all the control values from first.aspx, i added directive to second.aspx
<%# PreviousPageType VirtualPath="~/PR.aspx" %>
I have no problem to get all the previous page controls and set it to labels, but i have a big problem to save those values to a private variable, and reuse it after page load event is done. Here is code example. when i try to get the value from input in another method, it has nothing added. Why?
public partial class Second : System.Web.UI.Page
{
List<string> input = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if (Page.PreviousPage != null&&PreviousPage.IsCrossPagePostBack == true)
{
TextBox SourceTextBox11 (TextBox)Page.PreviousPage.FindControl("TextBox11");
if (SourceTextBox11 != null)
{
Label1.Text = SourceTextBox11.Text;
input.Add(SourceTextBox11.Text);
}
}
}
protected void SubmitBT_Click(object sender, EventArgs e)
{
//do sth with input list<string>
//input has nothing in it here.
}
}
The SubmitBT_Click-click event happens in a postback. But all variables (and controls) are disposed at the end of the page's lifecycle. So you need a way to persist your List, e.g. in the ViewState or Session.
public List<String> Input
{
get
{
if (Session["Input"] == null)
{
Session["Input"] = new List<String>();
}
return (List<String>)Session["Input"];
}
set { Session["Input"] = value; }
}
Nine Options for Managing Persistent User State in Your ASP.NET Application

Viewstate null on postback

So I have a listbox on my page and some textfields. Through the textfields I can add an item to my listbox (click the button, it adds it to a private List which is then set as a ViewState and the list is databound again). My listbox is also in an updatepanel which gets triggered on the button's Click event. Problem: My Viewstate remains null on a postback so it gets reset each time.
Some code:
private const string VIEW_INGREDIENTS = "IngredientsList";
private const string VIEW_LANGUAGE = "CurrentLanguage";
private List<IngredientData> _ingredientsList;
protected void Page_PreInit(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (ViewState[VIEW_INGREDIENTS] != null)
{
_ingredientsList = (List<IngredientData>) ViewState[VIEW_INGREDIENTS];
}
}
else
{
// prepare ingredient lists
_ingredientsList = new List<IngredientData>();
}
}
protected void Page_Load(object sender, EventArgs e)
{
lstIngredients.DataSource = _ingredientsList;
lstIngredients.DataTextField = "Text";
lstIngredients.DataValueField = "Name";
lstIngredients.DataBind();
}
protected void btnAddIngredient_Click(object sender, EventArgs e)
{
_ingredientsList.Add(new IngredientData { Name = txtIngredientName.Text, Quantity = txtUnitQuantity.Text, Unit = lstUnits.SelectedValue });
ViewState[VIEW_INGREDIENTS] = _ingredientsList;
lstIngredients.DataSource = _ingredientsList;
lstIngredients.DataBind();
}
You're using vewstate during PreInit ? Try to check that a bit later during PreLoad.
Check if the page has EnableViewState="true":
<%# Page Language="C#" EnableViewState="true" ...
And verify the site-wide setting in web.config:
<pages enableViewState="true" enableViewStateMac="true" ... />
Now ASP.NET has built-in viewstate for list controls, so I wonder why you're writing custom code for it. The default viewstate should work well for what you're trying to accomplish.

ASP.NET: Changing a site's culture programmatically

i'm trying to set my website's culture programmatically, so when a user clicks a button they can change the text on the page from english to spanish. here's my code:
protected void btnChangeLanguage(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("es");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("es);
}
<asp:Label ID="lblDisplay" runat="server" meta:ResourceKey="lblDisplay" />
<asp:Button ID="btnChangeLanguage" runat="server" Text="Change Language"
OnClick="btnChangeLanguage_Click" />
i have a Default.aspx.resx file with a key/value of: lblDisplay.text/English
and a Default.aspx.es.resx file with a key/value of: lblDisplay.text/Espanol
i can't get my Label's text to change from "English" to "Spanish". anyone see what i'm doing wrong?
ASP.Net threads are used for the lifetime of one request, not a user's entire session. Worse, sometimes the framework will recycle the same thread to handle additional requests rather than return it to the pool and get a new one (it's not that big a deal because the next request will initialize the culture again, but still).
Instead, you need to override the InitializeCulture() method for your page. See this link for more detail:
http://msdn.microsoft.com/en-us/library/bz9tc508.aspx
Create Session variable called "CurrentUI". and change it on link buttons event
eg:
Here i have two link buttons for each language
protected void EnglishLinkButton_Click(object sender, EventArgs e) {
Session["CurrentUI"] = "en-US";
Response.Redirect(Request.Url.OriginalString);
}
protected void SinhalaLinkButton_Click(object sender, EventArgs e) {
// සිංහල (ශ්‍රී ලංකා)
Session["CurrentUI"] = "si-LK";
Response.Redirect(Request.Url.OriginalString);
}
Now you need to override the InitializeCulture() in the base class of page
protected override void InitializeCulture() {
if (Session["CurrentUI"] != null) {
String selectedLanguage = (string)Session["CurrentUI"];
UICulture = selectedLanguage;
Culture = selectedLanguage;
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new
CultureInfo(selectedLanguage);
}
base.InitializeCulture();
}
Note that I used
//Response.Redirect(Request.Url.OriginalString);
after assigning culture key into the session in order to create a second post back to the page.
Because InitializeCulture() happens before the event and change will be applicable in the next request only.

Accessing Events And Members In The Master Page

I have an event in the Master page that I want to access in the pages that use that master page but it doesn't seem to be working.
In the Master
public delegate void NotifyRequest(object sender, EventArgs e);
public class MyMaster
{
public event NotifyRequest NewRequest;
protected void uiBtnNewTask_Click(object sender, EventArgs e)
{
if(NewRequest!= null)
NewRequest(this, e)
}
}
Inherited Page
MyMaster mm = new MyyMaster();
mm.NewRequest += new NotifyRequest(mm_NotifyRequest);
void mm_NotifyRequest(object sender, EventArgs e)
{
Label1.Text = "Wow";
this.Label1.Visible = true;
}
My problem is the event is always null. Any ideas?
You probably need to use the following syntax to access your event in the Master Page
((MyMaster)Master).NewRequest += new NotifyRequest(mm_NotifyRequest);
If you wish to access members of a master page you need to use the page Master attribute and cast it to your master page.
Alternately
If you wish do not wish to use a cast you can use the #MasterType directive to create a strong reference to your master page, in this case MyMaster. So you would be able to access your event like so: Master.NewRequest.
More Reading about Master Pages

Resources