ASP.Net - How to access masterpage Object from regular page? - asp.net

In a project I'm working on, the master page codebehind does a load of complex checks and confirmations that decide the navigation list displayed on the TreeView of the page. Now, I need a way to access this list from another front-end page, such as "frontpage.aspx".
This serves two purposes. One, the masterpage will hide pages on the navigation list the user shouldn't have access to, but the user can still enter the page by typing the page name into the URL manually. By being able to browse through the TreeView, I can isolate the whole authorization into a single method by simply checking if the page name exists within the currently used TreeView.
Two, this will allow me to easily change the displayed content of any page without checking the database or storing sessions for whatever specific rights the current user has, as I can just look if the TreeView contains "Products Admin" for example, and then use that to hide or display the section of the page that has to do with "Product Admin" functionality.
So, any tips on how to do this, or if it's even possible?

Assuming that frontpage.aspx is a content page you can definitely access the master page from it.
For example this code will find a TextBox and Label controls that are on the master page. You should be able to adapt it to find your TreeView:
// Gets a reference to a TextBox control inside a ContentPlaceHolder
ContentPlaceHolder mpContentPlaceHolder;
TextBox mpTextBox;
mpContentPlaceHolder =
(ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
if(mpContentPlaceHolder != null)
{
mpTextBox = (TextBox) mpContentPlaceHolder.FindControl("TextBox1");
if(mpTextBox != null)
{
mpTextBox.Text = "TextBox found!";
}
}
// Gets a reference to a Label control that is not in a
// ContentPlaceHolder control
Label mpLabel = (Label) Master.FindControl("masterPageLabel");
if(mpLabel != null)
{
Label1.Text = "Master page label = " + mpLabel.Text;
}
For more info see - http://msdn.microsoft.com/en-us/library/c8y19k6h.aspx

You should be able to access it through the Master property, i.e.:
TreeView tv = Master.MyTreeViewControl;
or
TreeView tv = (TreeView)Master.FindControl("MyTreeViewControl");
This page on MSDN has more information about working with master pages programmatically.

You can access any public functions from the masterpage refering to Page.Master and casting this property to your master-page;
((Styles_Master)Page.Master).IsMyProperty = "new value";

Related

ASP.Net c# - URL Parameter weird behaviour

I'm doing some URL changing to add some id values onto the end when certain components are clicked by the user.
So for example, when I'm logged into my AdminCP I have a list of user accounts which can have various things done to them, like modify the information or delete the user accounts.
The ASP.NET page i'm using is designed off a Master Page. That Master Page is also part of the Global Master page. So, like a nested master page.
When the user account is clicked, I record the Username in a Session Variable and then call that on page load with a button postback url. For example;
protected void Page_Load(object sender, EventArgs e)
{
if (Session["QueryString"] != null)
{
AdminHiddenButtonDelete.PostBackUrl = Request.Url.AbsolutePath + Session["QueryString"].ToString();
}
}
I'm setting the Session["QueryString"] when a button event is fired.
private void DeleteUser(string user)
{
admin_user_accounts_wrapper.Style.Add("display", "none");
admin_user_accounts_user_delete.Style.Add("display", "block");
Session["ClickedUserAccount"] = user; // This session is used to hold the username of the clicked useraccount
Session["QueryString"] = "?User = " + user + " ";
admin_user_account_user_delete_heading.InnerText = "Are you sure you wish to delete the user account " + user + "?";
}
This is called when the user clicks the html <button /> on the website.
Where query string houses the user accounts name. The outputted URL should then be url.aspx?User=John for example. Except, it always seems to be one postback behind. So, if I navigate to the John user, and then to the Rick user, the Rick URL will state John, and when I go back to the John user the URL will show Rick.
I hope this makes sense! I'm just not entirely sure on the best way to accomplish this.
To anyone who may of done something similar to me I want to post my answer on how I fixed this in hopes it may help other people out there.
The first thing I did was go back to some sort of basics about dynamic content, and realised I should be using an AJAX Update Panel to decrease the amount of postbacks that was happening.
The next thing I did was go through all my code line by line. I programmatically made a content container that houses for div id's and also some HTML buttons. These HTML buttons when clicked fired a JavaScript function. This function then called two hidden <asp buttons. That is where my mistake started.
The JavaScript function called a click event;
var hiddenButton = $('#<%= AdminHiddenButtonDelete.ClientID %>');
if (hiddenButton != null) {
hiddenButton.click();
This was my first mistake. I had now gotten two buttons, with one button doing a click server command twice, two post backs.
So, after removing the two hidden buttons and all the javascript I then needed to change the way I coded the content.
I swapped to using WebControls.Button and putting the contentResolver in the aspx.cs rather then its own class, then on click using new EventHandler(this.UserDelete_Click);
This tied the eventClick to my own function, allowing me to register the onClick event without postpacking as I'm using update panels.

While adding multiple web user control, an error occurs "only one instance of a ScriptManager can be added to the page"

I have created a user control "Calendar" of ajax date extender along with a text box for taking the date. Now im trying to create this control dynamically for all the rows populating in my table. Its gives the following error :-
Only one instance of a ScriptManager can be added to the page.
here's the code :-
tc = new TableCell();
tc.Style["width"] = "15%";
Calendar1 = (ASP.Calendar)LoadControl("../Calendar.ascx");
Calendar1.ID = "tbDate" + Convert.ToString(_id);
tc.Controls.Add(Calendar1);
tr.Cells.Add(tc);
tc.Dispose();
tc = null;
And i've declared a global variable :- public ASP.Calendar Calendar1;
Thanks in advance for ur suggestions.
You need to use the ScriptManagerProxy component inside your web usercontrol instead of a full-blown ScriptManager. The ScriptManagerProxy was created just for this kind of use that you want.
"Enables nested components such as content pages and user controls to add script and service references to pages when a ScriptManager control is already defined in a parent element." - http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanagerproxy.aspx
So basically make sure you use a ScriptManager on the calling page itself and use the ScriptManagerProxy component inside your Calendar.ascx web user control.
If your design don't really allow for that, how about creating a second version of Calendar.ascx only to be used as a nested control?
You have included the script manager more than once in your page, possibly in the user control itself.

Can not get Request.Form.Get valus from aspx page that wrappe withe ContentPlaceHolder (form error)

I am writing a web app in asp.net I have a master page that contain a ContentPlaceHolder
and a form that wrapper the ContentPlaceHolder, In a aspx page I realize the ContentPlaceHolder and have some controls in this page.
Now when I Trying to use Request.Form.Get("my control name") (from the aspx behind code), I get null.
If I try to add a form in the aspx page I get an error that say you can have only one form in a page.
How can i get the values in my controls??
thanks for the help.
Request.Form("YourControlName") will not work with server controls because ASP.NET adds some extra stuff to the name of your control when it outputs it to the page. It does this to make sure that the name remains unique across all the controls on the page. So, for example, your control might actually be named something like "ctl00_maincontent_placeholder1_YourControlName" when it gets created on the page.
In ASP.NET this is not usually a problem because you typically do NOT use Request.Forms to get your control values. Instead you use the server control's methods to get the values. So, for a textbox, you would use YourControlName.Text to get the value that was entered into the textbox.
If you are just trying to communicate a value between the master and page, assuming the value is on the master you can cast Page.Master to the correct type. On the master page you can wrap controls on the master.
MasterPage
public string MyControlText
{
get
{
return myControl.Text;
}
set
{
myControl.Text = value;
}
}
On the page
((MyMasterPage)this.Page.Master).MyControlText = "To master from page";
string fromMasterToPage = ((MyMasterPage)this.Page.Master).MyControlText;

Using javascript on an aspx page that uses a master page, which contains the page in a form?

I have a master page which contains everything that inherits it within a form. A page inheriting from it needs to run some javascript to act on a text field on a page. However, I can't seem to reference that text field through the javascript, since the form begins on the master page.
The following line will come up bogus:
document.form1.txtFindUser.value = blah.responseText;
This is because form1 is defined on the master page, while txtFindUser is on the current page.
How can these situations be handled?
How about that :
document.getElementById('txtFindUser').value = blah.responseText;
But if txtFindUser is your server control's id, then you should use the code above like that :
document.getElementById('<%= txtFindUser.ClientID %>').value = blah.responseText;
Page elements don't always have the same name at runtime than they do in design time in .NET. View the source of your page when you ran it and see what txtFindUser is called after it was interpreted by IIS.
any server controls on the page will render with a different name since that page is derived from a master page. (I guess this removes complexities which can arise out of using same names for controls in your master page as well as in the derived page).
var ctrl = '<%= txtBox1.ClientID %>';
document.getElementById(ctrl).value='Hello world';
Refer to this post for more info

Is there a way to load a usercontrol if you don't have access to Page?

How can I dynamically load a usercontrol in ASP.NET if I dont have access to a Page object (say I'm in a utility class)?
Normally you would do :
Page.LoadControl("~/controls/MyControl.ascx");
You could add a control from your utility class to the current page, using the following code:
Page currentPage = HttpContext.Current.Handler as Page;
if (currentPage != null)
{
currentPage.Controls.Add(
currentPage.LoadControl("~/controls/MyControl.ascx"));
}
It works, but I would not recommend this and consider it a hack.
The only way to load a user control properly (that is to say in a way that will initiate its life-cycle) is to add it to the control collection of another control.
So you will either need to pass in a reference to the page or a reference to a control that is on the page and add the control to that control's collection.

Resources