I have a weird scenario but this was how it was designed before me. Basically I have userControl, and there is a child.masterpage
in the userControl in the ascx file it contains the following
<div><%=_template%></div>
the child.masterpage inherits from a parent.masterpage, in the child.masterpage there is a call to the userControl
<asp:Content><ucc:UserControl></ucc>
the parent.masterpage has other fields in it and it has a .cs file with a c# function
public void passVal(string s)
Now what I want to do is to pass a value from the user control directly to the parent.masterpage function so that I can put it in the parent.masterpage literal I have created.
How can I achieve this (again, this is existing design and I cant turn things around) I am just adding a functionality.
<%# Master Language="C#" AutoEventWireup="true" MasterPageFile="../common/main.master" %>
<%# Register Src="UserControl.ascx" TagName="Ord" TagPrefix="uc" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
<div class="in"><uc:OrderReceipt ID="myord" runat="server" Visible="true"/>
<div style="margin-bottom:30px;">
Back to Home Page
</div>
</asp:Content>
You can use the Page.Master property to get a hold of the master page instance.
protected someEvent(object sender, EventArgs e)
{
(Page.Master as ChildMaster).passVal("some string");
}
More of an Answer:
I was just reviewing your OP and realized something. The code that kept puzzling me was the user control.
in the userControl in the ascx file it
contains the following
<div><%=_template%></div>
I haven't seen the code behind but my guess is that the user control is simply used to output dynamic HTML. I bet if you looked at the code behind (.cs file) of the user control, you would find a variable called _template. It is a string variable that is pumped with html at run time.
Now, that doesn't answer your question but, if you didn't already know that ... it is good to know =P
Now, the next mystery is the one concerning your missing code behind file for the child master page.
My theory is that whoever made it did it with some error that would cause it not to automatically generate a code behind file. Or, they made it from scratch and just simply added it to the project but neglected to make a code behind as well.
I made a master page, then made another one called child. I am able to subclass it and here is what the markup and code behind look like.
<%# Master Language="C#" MasterPageFile="~/Master.master" AutoEventWireup="true" CodeFile="Child.master.cs" Inherits="Child" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server">
</asp:Content>
public partial class Child : Master
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
In comparing the markup to yours, the key difference here is that mine explicitly mentions a CodeFile attribute.
Create a new cs file and following the naming convention. Then add the CodeFile and Inherits attributes to your child master page. This should wire everything up correctly and allow you to start adding methods and such to the child master page.
Let me know where you are at and we'll take it from there. GL
Related
I have to find a Control in an aspx page bound to a master page.
The master page contains:
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
The content page contains:
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
I added a Table with ID formtable as a child of Content2.
I tried to use the following code to access the Table, but the code returns null:
protected void Ok_Click(object sender, EventArgs e)
{
Table tblForm = this.FindControl("MainContent").FindControl("formtable") as Table;
}
How can I access the Table?
Try this
Table tblForm = this.Master.FindControl("MainContent").FindControl("formtable") as Table;
Checkout this Control ID Naming in Content Pages for more details
Working with findControl() cause complications sometimes.
It is easier to define a public property for that control in master page and then access control through the property.
you should add this line in child page:
<%# MasterType VirtualPath="~/MasterPage.master" %>
What context are you in when you are trying to do this? Are you in the codebehind of the individual page?
If you are it should be Content1.FindControl("formtable") as Table and that would be it.
I have 5 files.
Default.aspx
Search.ascx
SearchSQL.ascx
Grid.ascx
GridSQL.ascx
I have registered the ascx files in the default.aspx page and use properties to expose the controls to the default page. And that works great.
My issue is how do I send data back and fourth between the different ascx pages? If I register on any of those it will give me a Circular file reference error.
Using public properties, I have the Search.ascx registered on the GridSQL.ascx to pass the search parameters into Gridsql string, and then the GridSQL.ascx on the Grid.ascx file to pass the sql string to the grid databind.
There has got to be a much easier way to pass data BACK & FOURTH between pages, or am I wrong? When you try to register on the other page to pass data back to the page that sent it, you get the circular file reference error. I have heard a few resolutions like changing file structure, which I have tried, and also about Batch, but that kills performance. Believe i have spent days trying to find resolutions on this. I was going to comment on some questions but Stack does not allow me until I have 50 Rep.
My company is requiring us to use all separate files from now on and I just cant believe this is the best way to communicate between user controls.
Proper way is you want to bubble up the child control's event to parent.
Then let parent to forward the event to other controls.
Note: Here is the demo. You might want to rename delegates and methods which make sense to your scenario.
Search (User Control which fires the event)
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="Search.ascx.cs" Inherits="DemoWebForm.Search" %>
<asp:TextBox runat="server" ID="SearchTextBox" />
<asp:Button runat="server" ID="SearchButton"
Text="Search" OnClick="SearchButton_Click" />
public delegate void MessageHandler(string searchText);
public partial class Search : System.Web.UI.UserControl
{
public event MessageHandler SearchText;
protected void SearchButton_Click(object sender, EventArgs e)
{
SearchText(SearchTextBox.Text);
}
}
GridSql (User Control)
Finally, GridSql.ascx receives the search text.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="GridSql.ascx.cs" Inherits="DemoWebForm.GridSql" %>
<asp:Label runat="server" ID="SearchTextLabel"/>
public partial class GridSql : System.Web.UI.UserControl
{
public void SearchTextMethod(string searchText)
{
SearchTextLabel.Text = searchText;
}
}
Parent
<%# Page Language="C#" AutoEventWireup="true"
CodeBehind="Parent.aspx.cs" Inherits="DemoWebForm.Parent" %>
<%# Register src="~/Search.ascx" tagname="Search" tagprefix="uc1" %>
<%# Register src="~/GridSql.ascx" tagname="GridSql" tagprefix="uc2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<uc1:Search ID="Search1" runat="server" />
<uc2:GridSql ID="GridSql1" runat="server" />
</form>
</body>
</html>
public partial class Parent : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Search1.SearchText += m => GridSql1.SearchTextMethod(m);
}
}
I have two master pages in my C# MVC application. What I would like to be able to do is use one, or the other depending on the users 'role'. Something similar to this (obviously with a little more validation etc):
<% if(User.IsInRole("One")) { %>
<%# Page Language="C#" MasterPageFile="~/Views/Shared/One.Master"
Inherits="System.Web.Mvc.ViewPage<MyApp.Data.ProductData>" %>
<% } else if { %>
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Other.Master"
Inherits="System.Web.Mvc.ViewPage<MyApp.Data.ProductData>" %>
<% } %>
I've seen answers where this can be done to elements of a page, for example a menu, an image, etc. Is it possible to do it for the entire master page? In my situation, depending on the role, different css, images, colours will be used so it is necessary to use a different master page.
If anyone could help I'd be very grateful, or if anyone has any alternative (and probably better) solutions I'd also be grateful.
Thanks.
As you are using ASPX View in ASP.net MVC Application.
ASP.net MVC ASPX ( Webform) view still derive from Page class so you can use following code in
your aspx view.
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<script language="C#" runat="server">
protected void Page_PreInit(object sender, EventArgs e)
{
if (User.IsInRole("Admin"))
{
this.MasterPageFile = "~/Views/Shared/Site2.Master";
}
else
{
this.MasterPageFile = "~/Views/Shared/Site.Master";
}
}
</script>
You can change it dynamically via ViewMasterPage.MasterPageFile.
I would suggest making the selection in your Masterpage file rather than selecting which masterpage file to use.
This is driving me crazy. In the past I have been able to have a master page, put a user control on that page, and create a read-only property referencing that usercontrol, and access the usercontrol and all its properties from the derived page. Now I am getting this error:
The type ‘XXXX’ is defined in an assembly that is not referenced. You must add a reference to assembly 'App_Web_2zw4yn55, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
I looked at older projects and see that I was able to do this. I am using .Net 4.0 now, but not sure that is an issue.
My page declarations look like this...
Master Page:
<%# Master Language="C#" AutoEventWireup="true" CodeFile="Main.master.cs" Inherits="MasterPages_Main" %>
<%# Register src="../UserControls/WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %>
<uc1:WebUserControl ID="WebUserControl1" runat="server" />
Code Behind for Master Page:
public UserControls_WebUserControl TheWebControl { get { return this.WebUserControl1; } }
Derived Page:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPages/Main.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%# MasterType VirtualPath="~/MasterPages/Main.master" %>
<%# Reference VirtualPath="~/MasterPages/Main.master" %>
Code Behind for Derived Page:
protected void Page_Load(object sender, EventArgs e)
{
Master.TheWebControl.Pagetitle = "Hey";
}
If I put a reference, in the page declarations of the derived page, for the usercontrol it works, but I shouldn’t have to do that. I am not sure what is going on. I have never had to do this before. The only thing I can think of is that my web.config was setup differently, but even in my old pages I am not seeing any direct references to the usercontrol.
UPDATE:
I may have been mistaken. Looking back at the older code again, I did, indeed, add a reference in the page directives to the usercontrol on the derived page.
Perhpas there is anohter way of doing this without having to add the directive?
I was mistaken. Looking back at the older code again, I did, indeed, add a reference in the page directives to the usercontrol on the derived page.
I created Master page which has got mainNavigator panel on top of page that is a web user control(BuildMenu.ascx). I am filling UC Menu in master page's loading :
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="IntermMaster.master.cs" Inherits="MyProject.IntermMaster" EnableViewState="true" %>
<%# Register src="Utils/BuildMenu.ascx" tagname="BuildMenu" tagprefix="uc1" %>
>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<uc1:BuildMenu ID="BuildMenu2" runat="server" />
</div>
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
This is loading in postback event:
BuildMenu.ascx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Fill Menu from DataBase (Compare SiteMap...)
}
Every post back BuildManu.ascx is loading every time tihs is really bored me. How can i solve it. I want to do only one time load BuildMenu.ascx (in master page)
Unless you want to use frames (and you probably do not), the control has to be reloaded each time so it can be rendered. The best you can do is to use server-side output caching so that it takes less processing time to load the control.
To do output caching, put this in your page:
<%# OutputCache Duration="[Number of Seconds]" VaryByParam="None" %>
The load method WILL be called every time a postback occures (except for AJAX pages, but let's not go there). Take a look at the ASP.NET page lifecycle.
What you can do is just return from the controls Load event if the value of IsPostBack is true.
However, if the control in question is static (or almost static) in content you could try using output cashing on the server, that way the control will be loaded once in a while, and the rest of the times, the server will just use it's cashed copy.
i have a better idea why dont you sue a session it will help you
make like this ::
protected void Page_Load(object sender, EventArgs e)
{
if session(ispostback") <> "menuloaded"
{
// Fill Menu from DataBase (Compare SiteMap...)
Session("ispostback")="menuloaded"
}
this will work for sure