How to use control state in asp.net - asp.net

Below is my simple code to use control state in a custom control,
[DefaultProperty("Text")]
[ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
public class WebCustomControl1 : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get { return text; }
set { text = value; }
}
private string text;
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
protected override void OnInit(System.EventArgs e)
{
base.OnInit(e);
Page.RequiresControlState(this);
}
protected override object SaveControlState()
{
object baseSate = base.SaveControlState();
return new Pair(baseSate, Text);
}
protected override void LoadControlState(object savedState)
{
Pair value = savedState as Pair;
text = value.Second;
}
}
But it doesn't seem to work.. The SaveControlState and LoadControlState are not firing. can someone help me..?
Below is the aspx Code. Here is where i use the custom control.
<%# Page Language="C#" AutoEventWireup="true" EnableViewState="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%# Register Assembly="WebApplication1" Namespace="WebApplication1" TagPrefix="cc1" %>
<!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>`enter code here`
<body>
<form id="form1" runat="server">
<div>
<cc1:WebCustomControl1 ID="WebCustomControl1_1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" /></div>
</form>
</body>
</html>

You've called RequiresControlState
Determines whether the specified Control object is registered to participate in control state management.`
But you should call RegisterRequiresControlState
Registers a control as one whose control state must be persisted.

Related

Can a Templated User Control be used for data entry?

I've found code examples that demonstrate templated user controls. They work fine for displaying data, but I can't get them to work for entering data. I have a TextBox in my template, and can change the value in it, but I can't get that changed value in my code. I attempt to get the user control's values in a button click handler, but I always get just the initial value. Also, when I click the button, the templated user control's value(s) are reset. Is data entry supposed to work with templated user controls?
My code is similar to the MSDN topic "How to: Create Templated ASP.NET User Controls".
Default.aspx ===============================
<%# Page Language="C#" %>
<%# Register TagPrefix="uc" tagname="TemplateTest" Src="TemplatedUC.ascx" %>
<!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">
<script runat="server">
protected void Page_Load()
{
DataBind();
}
protected void ButtonShowContent_Click(object sender, EventArgs e)
{
ContentLabel.Text = string.Format("Index: {0} - Message: {1}<br>", TemplateTest1.Index, TemplateTest1.Message);
}
</script>
<head runat="server">
<title>Templated User Control Test</title>
</head>
<body>
<h1>Testing Templated User Control</h1>
<form id="Form2" runat="server">
<uc:TemplateTest ID="TemplateTest1" runat="server">
<MessageTemplate>
Index: <asp:Label runat="server" ID="Label1" Text='<%# Container.Index %>' /><br />
Message: <asp:TextBox runat="server" ID="Label2" Text='<%# Container.Message %>' /><br />
</MessageTemplate>
</uc:TemplateTest>
<asp:Button ID="ButtonShowContent" runat="server" Text="Show Content" onclick="ButtonShowContent_Click" />
<asp:Label ID="ContentLabel" runat="server" Text=" " Width="100%" />
</form>
</body>
</html>
TemplatedUC.ascx ============================
<%# Control Language="C#" ClassName="TemplatedUC" %>
<%# Import Namespace="System.ComponentModel" %>
<script runat="server">
private ITemplate messageTemplate = null;
private MessageContainer container = new MessageContainer(1, "Initial Text");
[ TemplateContainer(typeof(MessageContainer)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MessageTemplate {
get
{
return messageTemplate;
}
set
{
messageTemplate = value;
}
}
public int Index
{
get { return container.Index; }
set { container.Index = value; }
}
public string Message
{
get { return container.Message; }
set { container.Message = value; }
}
void Page_Init() {
if (messageTemplate != null) {
messageTemplate.InstantiateIn(container);
PlaceHolder1.Controls.Add(container);
}
}
public class MessageContainer: Control, INamingContainer {
private int m_index;
private String m_message;
internal MessageContainer(int index, String message)
{
m_index = index;
m_message = message;
}
public int Index {
get { return m_index; }
set { m_index = value; }
}
public String Message
{
get { return m_message; }
set { m_message = value; }
}
}
</script>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
If you run this and change the value for 'Message', then when you click the button, the data will be displayed. Thank you.

Access a content page variable through the master page

I know in ASP.net, we can access a master page variable through content page, but is there anyway we can access a content page variable through the master page?
Yes you can. You have to implement a base class and content class should be derived from that base class.
EDIT : Posted markup and changed code for a clearer example
I have created a base page inherited the System.Web.UI.Page, then made the content page inherit it. My basepage:
namespace WebApplication2
{
public class BasePage : System.Web.UI.Page
{
public BasePage() { }
public virtual string TextValue()
{
return "";
}
}
}
Here's my content page markup:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<asp:Label ID="lblContentText" Text="Contentpage TextValue:" runat="server"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</asp:Content>
Content page code:
namespace WebApplication2
{
public partial class _Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
public override string TextValue()
{
return TextBox1.Text;
}
}
}
My Masterpage markup:
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication2.SiteMaster" %>
<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="utf-8" />
<title><%: Page.Title %> - My ASP.NET Application</title>
<asp:ContentPlaceHolder runat="server" ID="HeadContent" />
</head>
<body>
<form runat="server">
<header> </header>
<div id="body">
<asp:Label ID="lblText" runat ="server" Text="Masterpage Text :" />
<asp:TextBox ID="txtMaster" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Click to read content page TextValue " OnClick="Button1_Click" />
<asp:ContentPlaceHolder runat="server" ID="MainContent" />
</div>
<footer>
</footer>
</form>
</body>
</html>
And the implementation in masterpage code behind:
namespace WebApplication2
{
public partial class SiteMaster : MasterPage
{
BasePage Currentpage = null;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Currentpage = this.Page as BasePage;
if (Currentpage != null)
{
txtMaster.Text = Currentpage.TextValue();
}
}
}
}
If you see any error like BasePase is not recognized, Please make sure that either it is using same namespace(i.e. WebApplication2), or the namespace is added to the implementation page (i.e. using WebApplication2;).
Hope it helps!

Click event on div in asp.net

I have a div in default.aspx with img inside as follow
<div id="sTab" class="tabs firsttab" runat="server">
<asp:Image ID="sTabImg" src="images/home.png" runat="server" />
Activities
</div>
I want to perform some action on click of the div in ASP.NET (not in javascript).
I tried the following
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
sTabImg.Attributes["onclick"] = ClientScript.GetPostBackEventReference(this, "ClickDiv");
}
protected void ClickDiv()
{
Label2.Text = "helo got it";
}
The page is getting refreshed and when i debugged the issue, its not entering the ClickDiv function..What wrong here..
From Here
public partial class _Default : System.Web.UI.Page, IPostBackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
div1.Attributes["onclick"]=ClientScript.GetPostBackEventReference(this,"ClickDiv");
}
protected void Div1_Click()
{
// Do something
}
#region IPostBackEventHandler Members
public void RaisePostBackEvent(string eventArgument)
{
if (!string.IsNullOrEmpty(eventArgument))
{
if (eventArgument == "ClickDiv")
{
Div1_Click();
}
}
}
#endregion
}
You have to implement the IPostBackEventHandler Interface.
Why not use ImageButton?
<%# Page Language="C#" AutoEventWireup="True" %>
<!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>
<title>ImageButton Sample</title>
<script language="C#" runat="server">
void ImageButton_Click(object sender, ImageClickEventArgs e)
{
Label1.Text = "You clicked the ImageButton control at the coordinates: (" +
e.X.ToString() + ", " + e.Y.ToString() + ")";
}
</script>
</head>
<body>
<form id="form1" runat="server">
<h3>ImageButton Sample</h3>
Click anywhere on the image.<br /><br />
<asp:ImageButton id="imagebutton1" runat="server"
AlternateText="ImageButton 1"
ImageAlign="left"
ImageUrl="images/pict.jpg"
OnClick="ImageButton_Click"/>
<br /><br />
<asp:label id="Label1" runat="server"/>
</form>
</body>
</html>
And you can see some examples here.

Image With Asp.Net Web Application

I have a problem with Images I have a image which is at root directory like “C:\Mh\mahesh1” and tried to upload by following ways but won’t works.
Defaults.aspx.cs
namespace UITI
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string img = MapPath("~Mh/mahesh1.jpg");
myimages.ImageUrl = img;
}
}
}
Defaults.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="UITI._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:Image ID="myimages" runat="server" BorderStyle="Double" />
</div>
</form>
</body>
</html>
I have also tried on Default.aspx.cs page like:
namespace UITI
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string img = ResolveClientUrl ("~/Mh/mahesh1.jpg");
myimages.ImageUrl = img;
}
}
}
How to do?.
try it
string img = Server.MapPath("~/Mh/mahesh1.jpg");
myimages.ImageUrl = img;
or
Edit:
string img = ResolveUrl("~/Mh/mahesh1.jpg");
myimages.ImageUrl = img;
If it not worked,please check your folder path (~/Mh/mahesh1.jpg). Your path is non correct. My above code is working to me
New Edit
string img = **ResolveUrl("mahesh1.jpg");**
myimages.ImageUrl = img;
See
first just try this for put correct url straightly
**myimages.ImageUrl = #"~/Mh/mahesh1";**
Problem is here:
Your mahesh1 image is inside of any other folder(for project folder or any other drive or desktop ) .So you got this problem . You can use any other image. or rename of your mahesh1 to mahes123 (if you like name) image then check.

ScriptManager.RegisterClientScriptBlock registering scripts twice

On the OnPreRender of my custom server control, I am registering an alert to popup everytime the page is loaded after a partial postback (add_pageLoaded(function() { alert('Hi')})). I only want this to be called once, but its gets called as many times as there has been partial postbacks. For example, in the code below, if you open the page and click "Click me" you get one alert, click again and you will get two alerts, three --> three alerts and so forth. My understanding was that ScriptManager.RegisterClientScriptBlock, using the scriptKey parameter was suppose to check if the script has already been registered, and if so, dont register it again.
I cannot register this script on !IsPostBack because my custom control will be inserted during Postbacks into pages, so using !IsPostBack will not include my script.
Here is a simple example of this problem:
ASPX:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RegisterClientScriptExperimentation._Default" %>
<%# Register Assembly="RegisterClientScriptExperimentation" Namespace="RegisterClientScriptExperimentation" TagPrefix="cc" %>
<!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>
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Panel ID="panel" runat="server"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
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.Text;
namespace RegisterClientScriptExperimentation
{
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
panel.Controls.Add(new CustomControl());
}
}
public class CustomControl : CompositeControl
{
private Button button;
public CustomControl()
{
button = new Button();
button.Text = "Click me";
}
protected override void CreateChildControls()
{
Controls.Clear();
Controls.Add(button);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
StringBuilder _text = new StringBuilder();
_text.Append("var prm = Sys.WebForms.PageRequestManager.getInstance();");
_text.Append("prm.add_pageLoaded(function() { alert('Page Loaded'); });");
if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true);
else
Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true);
}
}
}
if(!Page.ClientScript.IsClientScriptBlockRegistered("customControlScript") && !Page.IsPostBack)
{
if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true);
else
Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true);
}
I found the solution to this.
In your page events, after you execute whatever you need to do, you need to remove the function from the event which you hooked into.
For example:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(DoSomething);
function DoSomething() {
alert('Hello');
Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(DoSomething);
}

Resources