Reference masterpage variables from control in child page? - asp.net

Is it possible to access Masterpage variables from a web user control that is in a child page? I know you can access them in child pages by adding the following
<%# MasterType VirtualPath="~/Master.master" %>
It doesn't seem to work when trying to access from a Web control that is inside a child page

User Controls essentially should be unaware of any pages outside the control. The better approach would be to have the control expose properties and events that the page itself (master page or normal) will use to set and retrieve values. Take this simple example:
class PassValueEventArgs : EventArgs
{
public string Value { get; set; }
}
public event EventHandler<PassValueEventArgs> RequestingValue;
public void ControlDoingWork()
{
PassValueEventArgs e = new PassValueEventArgs();
if (RequestingValue != null)
{
RequestingValue(this, e);
}
string fromHandlingPage = "Received " + e.Value + " from a handling page.";
}
Then whenever the user control should have a value, the page containing the user control can just handle the RequestingValue event and send the value to the user control. Otherwise just expose a public property of the user control, which you can even make databound, for an even easier solution.
Adding a complete example of the event-driven approach:
WebUserControl1EventArgs.cs
public class WebUserControl1EventArgs : EventArgs
{
public double ValueToSquare { get; set; }
}
WebUserControl1.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplicationCS1_net20.WebUserControl1" %>
Text below will display "Nothing passed from parent page." if the event is unhandled,
else will display the square of the number passed if handled.<br /><br />
<asp:Label runat="server" ID="Label1" Font-Bold="true" Font-Size="Larger" Text="Nothing passed from parent page."></asp:Label>
WebUserControl1.ascx.cs
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public event EventHandler<WebUserControl1EventArgs> RequestingNumber;
protected void Page_Load(object sender, EventArgs e)
{
ControlDoingWork();
}
private void ControlDoingWork()
{
if (RequestingNumber != null)
{
WebUserControl1EventArgs e = new WebUserControl1EventArgs();
RequestingNumber(this, e);
Label1.Text = (e.ValueToSquare * e.ValueToSquare).ToString();
}
}
}
WebForm1.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplicationCS1_net20.WebForm1" %>
<%# Register src="WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc1" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:WebUserControl1 ID="WebUserControl11" runat="server"
OnRequestingNumber="WebUserControl11_RequestingNumber" />
</div>
</form>
</body>
</html>
WebForm1.aspx.cs
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void WebUserControl11_RequestingNumber(object sender, WebUserControl1EventArgs e)
{
e.ValueToSquare = 3.3;
}
}
WebForm2.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplicationCS1_net20.WebForm2" %>
<%# Register src="WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc1" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:WebUserControl1 ID="WebUserControl11" runat="server" />
</div>
</form>
</body>
</html>
WebForm2.aspx.cs
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

Use the Page's Master property to access to it's masterpage. After that you can you FindControl method or use the master's public properties if it have any. For example in the master page code behind:
public Label Title { get { return lblTitle; } }

Related

Setting UserControl properties dynamcally on Aspx page

Im making a generic modal usercontrol that i can call on different Aspx pages and set the text via parameter. First i created 2 properties on the Codebehind of my UserControl
public partial class _modalGenerica : System.Web.UI.UserControl
{
public string Body { get; set; }
public string Title { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Than i created the modal button on my ascx and tried to access the properties
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="_modalGenerica.ascx.cs" Inherits="GS1.CNP.WEBUI.views.backoffice.areaEstatica.formularioProduto._modalGenerica" %>
<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="<%this.Title%>" data-content="<%this.Body%>"> Click to toggle popover</button>
And lastly i call the UC on the the aspx page with this line
<partial:_modalGenerica runat="server" id="_modalGenerica" Body="Hhahaha" Title="Teste" />
The aspx page is not loading after i created the button modal, any ideas? or better solutions for this?

Using DisplayForModel with MVC4 and the ASPX View Engine

Using ASP.NET MVC4 (.NET 4, C#) on MSVC 2010 SP1, I've noticed that I can pass a class model to a view using Razor and display the model using DisplayModelFor & EditorForModel but when I try to do the same using the ASPX view engine it doesn't work. Why is that? Code snippets from my test project below. Thanks.
My Controller:
namespace MvcApplication1.Controllers
{
public class TestController : Controller
{
public ActionResult Index()
{
TestModelClass c = new TestModelClass();
c.MyInt = 999;
return View(c);
}
}
My Model:
namespace MvcApplication1.Models
{
public class TestModelClass
{
public int MyInt { get; set; }
}
}
My View:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.TestModelClass>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<%Html.DisplayForModel(); %>
</div>
</body>
</html>
Alternate Razor (Works):
#model MvcApplication1.Models.TestModelClass
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.DisplayForModel()
Successful output from Razor version:
Index
MyInt
999
You are missing a :.
The correct syntax should be
<%: Html.DisplayForModel() %>

Binding ViewModel Property to ASP TextBox and Button

This is my View
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="InsertUser.aspx.cs" Inherits="WebApplication1.InsertUser" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"></asp:ObjectDataSource>
<asp:TextBox></asp:TextBox> // i want to bind the Fullname Property here
<asp:Button></asp:Button> // i want to bind the Save() here
</div>
</form>
</body>
</html>
and i want to bind the property and method from my viewmodel. Is it possible?
this is my ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Services;
namespace Testing.ViewModel
{
public class UserVM
{
public int UserID { get; set; }
public string Fullname { get; set; }
[WebMethod]
public void Save()
{
}
}
}
can someone guide me to the right direction? i manage to bind the Grid with ObjectDataSource and i can perform CRUD operations but i cant manage to bind a View to a ViewModel.
this is my sample Binding from ViewModel with CRUD operation to my View with Grid
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title></title></head><body><form id="form1" runat="server">
<div>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Testing.Model.User" DeleteMethod="DeleteUser" InsertMethod="CreateUser" SelectMethod="GetUsers" TypeName="Testing.ViewModel.UserListVM" UpdateMethod="UpdateUser"></asp:ObjectDataSource>
<asp:GridView ID="GridView1" DataSourceID="ObjectDataSource1" runat="server" AllowPaging="True" AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowSelectButton="True" />
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
<asp:BoundField DataField="Fullname" HeaderText="Fullname" SortExpression="Fullname" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
UserListVM
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Testing.Model;
namespace Testing.ViewModel
{
public class UserListVM
{
public UserListVM()
{
}
public IEnumerable<User> GetUsers()
{
return VMIndex.Users;
}
public User UpdateUser(User user)
{
throw new NotImplementedException();
}
public User DeleteUser(User user)
{
throw new NotImplementedException();
}
public User CreateUser(User user)
{
throw new NotImplementedException();
}
}
}
Any help please.. Thanks in advance.

ASP.NET Content Web Form - content from placeholder disappears

I'm attempting to set a class on the body tag in my asp.net site which uses a master page and content web forms. I simply want to be able to do this by adding a bodycssclass property (see below) to the content web form page directive.
It works through the solution below but when i attempt to view Default.aspx the Content1 control loses its content. Any ideas why?
Here is how I'm doing it. I have a master page with the following content:
<%# Master Language="C#" ... %>
<html><head>...</head>
<body id=ctlBody runat=server>
<asp:ContentPlaceHolder ID="cphMain" runat="server" />
</body>
</html>
it's code behind looks like:
public partial class Site : MasterPageBase
{
public override string BodyCssClass
{
get { return ctlBody.Attributes["class"]; }
set { ctlBody.Attributes["class"] = value; }
}
}
it inherits from:
public abstract class MasterPageBase : MasterPage
{
public abstract string BodyCssClass
{
get;
set;
}
}
my default.aspx is defined as:
<%# Page Title="..." [master page definition etc..] bodycssclass="home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
Some content
</asp:Content>
the code behind for this file looks like:
public partial class Default : PageBase { ... }
and it inherits from :
public class PageBase : Page
{
public string BodyCssClass
{
get
{
MasterPageBase mpbCurrent = this.Master as MasterPageBase;
return mpbCurrent.BodyCssClass;
}
set
{
MasterPageBase mpbCurrent = this.Master as MasterPageBase;
mpbCurrent.BodyCssClass = value;
}
}
}
This works for me now...
public class PageBase : Page
{
public string BodyCssClass
{
get;
set;
}
protected override void OnPreInit(EventArgs e)
{
MasterPageBase mpbCurrent = this.Master as MasterPageBase;
mpbCurrent.BodyCssClass = BodyCssClass;
base.OnLoadComplete(e);
}
}
Have you tried adding the MasterType directive to your content page? Like so:
I recommend doing that anyway. Let's see if that helps you...
See http://msdn.microsoft.com/en-us/library/ms228274.aspx
and http://msdn.microsoft.com/en-us/library/c8y19k6h.aspx

Custom elements in ASP.NET with custom child-elements

I know that it is possible to define custom tags in ASP.NET with User Controls. But as far as I know you can only add attributes to these controls. I would like to be able to embed more complex data, a bit lite this:
<myControls:MyGraph id="myGraph1" runat="server">
<colors>
<color>#abcdef</color>
<color>#123456</color>
</colors>
</myControls:MyGraph>
It this possible in ASP.NET? Should I try to extend a ListView? Or it there a better and more correct solution?
It is certainly possible. For your example the classes would look like:
[ParseChildren(true)]
class MyGraph : WebControl {
List<Color> _colors = new List<Color>();
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<Color> Colors {
get { return _colors; }
}
}
class Color {
public string Value { get; set; }
}
And the actual markup would be:
<myControls:MyGraph id="myGraph1" runat="server">
<Colors>
<myControls:Color Value="#abcdef" />
<myControls:Color Value="#123456" />
</Colors>
</myControls:MyGraph>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
namespace ComponentDemo
{
[ParseChildren( true )]
public class MyGraph : System.Web.UI.WebControls.WebControl
{
private List<Color> _colors;
public MyGraph() : base() { ;}
[PersistenceMode( PersistenceMode.InnerProperty )]
public List<Color> Colors
{
get
{
if ( null == this._colors ) { this._colors = new List<Color>(); }
return _colors;
}
}
}
public class Color
{
public Color() : base() { ;}
public string Value { get; set; }
}
}
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ComponentDemo._Default" %>
<%# Register Assembly="ComponentDemo" Namespace="ComponentDemo" TagPrefix="my" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<my:MyGraph runat="server">
<Colors>
<my:Color Value="value1" />
<my:Color Value="value2" />
<my:Color Value="value3" />
<my:Color Value="value4" />
</Colors>
</my:MyGraph>
</div>
</form>
</body>
</html>
You cannot user UserControl for such purpoces. As adviced above, inherit Control or WebControl.

Resources