I've read every post I can find on how to do this and tried them all. I have a Master page called DNAStaff (at root) containing:-
<%# Master Language="C#" AutoEventWireup="true" CodeFile="DNAStaff.master.cs" Inherits="DNAStaff" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
<link href="~/Styles/DNA.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
...............
</div>
</form>
</body>
</html>
The Masterpage code behind includes:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.IO;
using System.Data;
public partial class DNAStaff : System.Web.UI.MasterPage
{
public string MyAccessLevel
{
get; set;
}
protected void Page_Load(object sender, EventArgs e)
{
string ConnectionString = "Data Source=NZ1;Initial Catalog=Intranet;Integrated Security=false;UID=IntranetAccess;PWD=*****";
string sqlstring = #"select [MenuID], [Item], Target, SecLevel from [MENUS] ";
SqlConnection conn = new SqlConnection(ConnectionString);
SqlDataReader rdr = null;
int MainGroup;
try
{
if (Request.Cookies["userinfo"] != null)
{
MyAccessLevel = Server.HtmlEncode(Request.Cookies["userinfo"]["accessLevel"]);
}
else
{
MyAccessLevel = "1";
}
.........
The content page includes:
<%# Page Title="" Language="C#" MasterPageFile="~/DNAStaff.master" AutoEventWireup="true" CodeFile="main.aspx.cs" Inherits="main" %>
<%# MasterType virtualpath="~/DNAStaff.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
Set Primary Project
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</asp:Content>
enter code here
and the content page code behind contains:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class main : System.Web.UI.Page
{
string AccessLevel = "";
protected void Page_Load(object sender, EventArgs e)
{
AccessLevel = Master.MyAccessLevel;
TextBox1.Text = AccessLevel;
}
}
The line "AccessLevel = Master.MyAccessLevel" gives an error:-
Error CS1061 'MasterPage' does not contain a definition for
'MyAccessLevel' and no extension method
'MyAccessLevel' accepting a first argument of type 'MasterPage' could be
found (are you missing a using directive or an assembly reference?)
8_Live_main.aspx D:\Development\dnanew.steelpencil.com\Live\main.aspx.cs
13 Active
I want to set the variable MyAccessLevel in the MasterPage at load and read it in any content page. I'm obviously missing something, can someone please help?
You can access the Master Page like this.
Site1 master = ((Site1)(Page.Master));
TextBox1.Text = master.AccessLevel;
Where Site1 is the class name of the Master Page (public partial class Site1 : System.Web.UI.MasterPage)
However you should know that the Master Page_Load is initialized at a later stage in the Page Life Cycle than the Page. So when you access the value of AccessLevel, it will always be empty.
See https://msdn.microsoft.com/en-us/library/dct97kc3.aspx
As in the content page already you have assigned the MasterType like below.
<%# MasterType virtualpath="~/DNAStaff.master" %>
So now your child/content page can able to use/access the master layout including the public variable/properties defined in the master page.
So now, as per your requirement, to access the public property(AccessLevel) defined in your master page and assign to the child/content page textbox, you need to write the below code
Site myMaster = ((Site)(Page.Master));
TextBox1.Text = myMaster .AccessLevel;
Hope it solves your problem.
Here are the more references about Master page and accessing the contents of master page
https://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
https://msdn.microsoft.com/en-us/library/xxwa0ff0.aspx
This post should answer your question.You must add
<%# MasterType VirtualPath="~/your page path" %>
directive to your page
Related
I have a simple hierarchy of nested master pages.
However, in runtime, the master page controls (exemplified by label1) are always null.
If Default.aspx is changed to use Base.master directly, the master page controls will be correctly defined.
What is the cause for this behavior?
Base.master
<%# Master Language="C#" CodeFile="Base.master.cs" Inherits="BaseMaster" %>
<!DOCTYPE html>
<html lang="en">
<head runat="server"></head>
<body>
<form runat="server">
<asp:Label runat="server" id="label1" Text="Label 1" />
<asp:ContentPlaceHolder runat="server" ID="MainContent" />
</form>
</body>
</html>
Base.master.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class BaseMaster : MasterPage
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
label1.Text = "Base"; // Causes NullReferenceException
}
}
Sub.master
<%# Master Language="C#" CodeFile="Sub.master.cs" Inherits="SubMaster" MasterPageFile="~/Base.master" CodeFileBaseClass="BaseMaster" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<asp:ContentPlaceHolder runat="server" ID="SubMainContent" />
</asp:Content>
Sub.master.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class SubMaster : BaseMaster
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
label1.Text = "Sub"; // Causes NullReferenceException
}
}
Default.aspx
<%# Page Language="C#" CodeFile="Default.aspx.cs" Inherits="DefaultPage" MasterPageFile="~/Sub.master" %>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="SubMainContent">
<h3>Default</h3>
</asp:Content>
Default.aspx.cs
using System;
using System.Web;
using System.Web.UI;
public partial class DefaultPage : Page
{
}
I am using WebForms and I am trying to perform Model Validation inside a Master-Page and for some reason the model is not picking up the values, meaning that after the validation fires if I enter a good value, the model keeps coming back empty hence triggering the validation over and over. If I put the code in page without Master-Page it works fine. I was able to put a very simple example and honestly, it's hard to believe that as common as MasterPages are, nobody has ran into this scenario so far. For the purpose of this example I embedded the Model in the Code Behind but having outside makes no different. Any idea will be greatly welcome. Thanks.
--Master-Page--
<%# Master Language="C#" AutoEventWireup="true" CodeFile="test.master.cs" Inherits="test" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
-- WebForm --
<%# Page Title="" Language="C#" MasterPageFile="~/test.master" AutoEventWireup="true" CodeFile="test3.aspx.cs" Inherits="test3" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div>
<asp:ValidationSummary ID="valSummary" runat="server" />
</div>
<div><label>First Name:</label></div>
<div><input type="text" id="FirstName" runat="server" /></div>
<div><label>Middle Name:</label></div>
<div><input type="text" id="MiddleName" runat="server" /></div>
<div><label>Last Name:</label></div>
<div><input type="text" id="LastName" runat="server" /></div>
<div>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
</div>
</asp:Content>
-- Code Behind --
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.ModelBinding;
using System.ComponentModel.DataAnnotations;
public partial class test3 : System.Web.UI.Page
{
public class testClass2
{
[Required()]
[MinLength(2)]
public string FirstName { get; set; }
public string MiddleName { get; set; }
[Required()]
[MinLength(2)]
public string LastName { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
testClass2 tc = new testClass2();
if (TryUpdateModel(tc, new FormValueProvider(ModelBindingExecutionContext)))
{
System.Diagnostics.Debug.WriteLine("test");
}
}
}
}
The problem is indeed caused by usage of the master page. When used outside of the data bound control (such as GridView, FormView, Menu, etc.), FormValueProvider expects to have the same keys in Request.Form dictionary as property names in model object.
If you will take a closer look at generated HTML you will see that all input tags in form with master page have name attribute value set to something like ctl00$ContentPlaceHolder1$FirstName, ctl00$ContentPlaceHolder1$LastName, etc. while form without master page leaves name attribute intact and equal to the value of control's ID property.
This is the way of how UniqueID is generated to avoid name duplication (which should be avoided because in Web Forms we can have only one form tag and thus have controls with same ID's both on master page and form page).
And this is the cause why FormValueProvider cannot get values for your testClass2 object, it just cannot find FirstName, LastName, MiddleName values in posted form.
I found a solution.You can write a little front-end code to set the name equal to id and don't forget to set ClientIDMode to Static
<script>
$("input[type=text]").each(function () {
var id = $(this).attr("id");
$(this).attr("name", id);
});
</script>
Here is all my code:
Site.Master
<%# Master Language="C#" AutoEventWireup="true"
CodeBehind="Site.master.cs" Inherits="WebApplication1.SiteMaster" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form runat="server">
<div class="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
</div>
</form>
</body>
</html>
Site.Master.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class SiteMaster : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Default.aspx
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="WebApplication1._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
</asp:Content>
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ListBox ListBox1 = new ListBox();
ListBox1.FindControl("ListBox1");
ListBox1.Items.Add(new ListItem("Hello"));
}
}
}
Question: Why is my ListBox not populating?
When running the code I get a page with a small box that is completely empty.
I tried the following already and I will tell you the result -
Remove
ListBox ListBox1 = new ListBox();
ListBox1.FindControl("ListBox1");
Result: The name 'ListBox1' does not exist in the current context
Add a reference to ListBox1 manually into the designer.
Result: Object reference not set to an instance of an object.
To fix that error adding the line ListBox ListBox1 = new ListBox(); works, but still does not display.
Any ideas? Thanks.
You should only need...
protected void Page_Load(object sender, EventArgs e)
{
ListBox1.Items.Add(new ListItem("Hello", "H"));
}
See this link too
EDIT: Same code works for me.
To directly answer your question of why ListBox1 isn't getting populated:
protected void Page_Load(object sender, EventArgs e)
{
ListBox ListBox1 = new ListBox(); //You are creating a new local ListBox named ListBox1.
ListBox1.FindControl("ListBox1"); //You are trying to find the Control named ListBox1 that is held within the Control ListBox1 (and not doing anything with the result of the search)
ListBox1.Items.Add(new ListItem("Hello")); //You are adding a new ListItem to the local ListBox1.
}
As christiandev said, you should just be able to do this:
protected void Page_Load(object sender, EventArgs e)
{
ListBox1.Items.Add(new ListItem("Hello"));
}
I have no idea why you can't seem to access the ListBox1 on the aspx page.
I need a value from javascript before the main page load and then want to use that value in code. The code which I am using for that purpose is:
I have make a test.aspx page. The code for which is as following:-
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title> <script type="text/javascript" language="javascript">
function GetScreenHeightAndWidth()
{
var width = screen.width;
var height = screen.height;
var object = 'Label1';
document.getElementById(object ).innerHTML=height ;
//alert(height);
'<%Session["Screensize"] = "' + height +'"; %>' ;
}
</script>
</head>
<body onload="GetScreenHeightAndWidth();" >
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="test"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</div>
</form>
</body>
</html>
The code for test.aspx.cs page is as following:-
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Windows.Forms;
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Session["Screensize"] = Label1.Text;
TextBox1.Text=Session["Screensize"].ToString();
}
}
The result is as following:-
768 test
while result what I need is 768 and 768.
Is there any way to solve the problem?
What you are asking is impossible to do. Why do you need to know the screen size on the server -side in the first place? Whatever you need to accommodate on the html produced by the server can be either adjusted via proper CSS rules or Javascript (JQuery if you prefer that framework)
If you set the width/height values to a hidden field from script, you can than access them from codebehind after a postback. Labels are not posted with the form so you cant use that.
First of all thanks to all of you for responding to my question. After much search I have found what I was exactly wanting. For this I have to use one more page and add this code in my original code:
if (!IsPostBack)
{
if (Session["ScreenResolution"] == null)
{
Response.Redirect("detectscreen.aspx");
}
else
{
Session["Screensize"] = Session["ScreenResolution"].ToString();
}
TextBox1.Text = Session["Screensize"].ToString();
}
And the code for new page is:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["action"] != null) {
Session["ScreenResolution"] = Request.QueryString["res"].ToString();
Response.Redirect("Catalogue.aspx");
}
}
and the script in the new page will be like this:
<script language="javascript" type="text/javascript">
res = "&res="+screen.height
top.location.href="detectscreen.aspx?action=set"+res
</script>
This is my code, on a .ascx page :
<% for (int i = 1; i <= 10; i++)
{ %>
<asp:TextBox ID="myTextBox_<%=i %>" runat="server" Width="100%" CssClass="focus_out reset_content"></asp:TextBox>
<% } %>
but I get myTextBox_<%=i %> is not a valid identificator. So, how can I put "Dynamic IDs"?
You need to create a container for the textboxes, such as a Panel control, and then use the Page_Load in the code behind to loop through and add the text boxes to the panel.
Example:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="pnlContainer" runat="server" />
</div>
</form>
</body>
</html>
Code behind:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++) {
TextBox txtNewTextBox = new TextBox();
txtNewTextBox.ID = "myTextBox_" + i;
pnlContainer.Controls.Add(txtNewTextBox);
}
}
}
Here is the link for Dynamically adding textbox control in ASP.Net. Hope it works for you.