Fire server event from client - asp.net

I am having trouble with the Asp.net page life cycle. I am trying to create a custom menu using HtmlTextWriter with an asp.net LinkButton to fire a server event. I can not get the server event to fire and I get the 'object reference not set to instance of object' when I click my linkbutton. Here is some code.
protected string CreateModuleMenu()
{
var modules = ModuleManager.GetModulesByDeveloperId(Developer.DeveloperID);
StringWriter sw = new StringWriter();
ClientScriptManager cs = Page.ClientScript;
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
foreach (var module in modules)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.RenderBeginTag(HtmlTextWriterTag.Dl);
writer.RenderBeginTag(HtmlTextWriterTag.Dt);
writer.Write(module.Name);
var files = ModuleManager.GetModuleFilesByModuleId(module.ModuleID);
foreach (var file in files)
{
writer.RenderBeginTag(HtmlTextWriterTag.Dd);
LinkButton lb = new LinkButton();
lb.ID = "mc" + file.ModuleFileID;
lb.Attributes.Add("onclick", cs.GetPostBackEventReference(lb, "LoadControl_Clk"));
lb.Text = file.Name;
Page.RegisterRequiresRaiseEvent(lb);
lb.RenderControl(writer);
writer.RenderEndTag();
}
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
}
return sw.ToString();
Here is my click event:
protected void LoadControl_Clk(object sender, EventArgs e)
{
Response.Write("Hello World");
}
Finally here is what I have in the Page_Load event. Note: I tried moving this around to PreRender, PreInt, etc.
protected void Page_Load(object sender, EventArgs e)
{
LiteralControl lit = new LiteralControl();
lit.Text = CreateModuleMenu();
phModuleMenu.Controls.Add(lit);
if (DefaultModuleFile == null)
Response.Write("Error.");
else
{
Control ctrl = LoadControl(DefaultModuleFile.Src);
phAdminModules.Controls.Add(ctrl);
}
}
Lost. Thanks.

Perhaps you need to only load the control in Page_Load on the first time the page is called, that is, if !IsPostBack.
If you load the control on every page load, you will lose the event being fired.

Related

Open link in a new window in ajax panel on server side

I have asked this question before, but got no answer that worked.
This is a buttonclick event that should initiate the download:
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
SendFileDownload(file);
}
One of the solutions that was offered was opening a link in a new window and have the window on page load initiate the download there with this piece of code:
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
// SendFileDownload(file); dont call it here , call it in the other window
string url = "PopupFileDownload.aspx?file="+file;
string s = "window.open('" + url + "', 'popup_window', 'width=300,height=100,left=100,top=100,resizable=yes');";
ClientScript.RegisterStartupScript(this.GetType(), "script", s, true);
}
This did not work. I tried doing something similar since I am using the Telerik Ajax Panel
ajaxPanel.ResponseScripts.Add("window.open('DownLoadPopup.aspx?file='" + file + "'', 'popup_window', 'width=300,height=100,left=100,top=100,resizable=yes');");
But this also did not work. the command was executed with no effect.
How can I send a file to the user without sacrificing the Ajax panel?
If your button's inside an ASP.NET Ajax UpdatePanel you could turn off the ajax for just the download button
ScriptManager.RegisterPostBackControl(btnDownload);
If you're using Telerik Ajax controls, you can use the following code to pop up a RadWindow.
Make sure you've got a RadScriptManager and a RadAjaxManager on your page before your RadAjaxPanel...
Then add a RadWindowManager inside your RadAjaxPanel like this...
<telerik:RadWindowManager runat="server" ID="rwm" Modal="true" Skin="Default" AutoSize="true" />
Then in your code, you can do this...
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
rwm.Windows.Clear();
var rWin = new RadWindow();
rWin.ID = "Name of my window";
rWin.NavigateUrl = string.Format("~/DownLoadPopup.aspx?file={0}", file);
rWin.Width = Unit.Pixel(1000);
rWin.Height = Unit.Pixel(600);
rWin.VisibleOnPageLoad = true;
rwm.Windows.Add(rWin);
}
Adjust the path to your DownLoadPopup.aspx and the properties of the RadWindow as necessary.

Asp.net create LinkButton and attach onclick event when another LinkButton is clicked

So.. I'm dynamically creating LinkButtons on my page like this:
LinkButton lb = new LinkButton();
lb.Click += new EventHandler(lb_Click);
When one of these LinkButtons is clicked, I need to know which one the links was clicked, then create another LinkButton and attach an onclick event on it. (How) can I do this? If I have understood correctly, click events can't be attached in (this case in) lb_Click function, so is there any way I still could do this?
Edited:
To make this problem more understandable, here's how I tried to make it but it does not work:
LinkButton lb = new LinkButton();
lb.click += new EventHandler(lb_Click);
void lb_Click(object sender, EventArgs e)
{
LinkButton lb2 = new LinkButton();
lb2.click += new EventHandler(lb2_Click);
}
void lb2_Click(object sender, EventArgs e)
{
//do something
}
Clicking lb2 does not fire the lb2_Click event.
You can try with this code - based on sender argument
LinkButton lb = new LinkButton();
lb.Id= "Test1";
lb.Click += new EventHandler(lb_Click);
LinkButton lb2 = new LinkButton();
lb2.Id= "Test2";
lb2.Click += new EventHandler(lb_Click);
void LinkButton_Click(Object sender, EventArgs e)
{
var yourControl = (LinkButton)sender;
var id = yourControl.Id;
if(id == "Test1")
{
...
}
else if(id == "Test2")
{
...
}
}
Yes, yes, yes: I'm very, very late to the party.
BUT for future reference of anyone coming to this post:
Your methods are marked as private (omitting an access modifier defaults to private), which means they are not accessible enough for them to be called.
Instead, use the protected modifier to ensure they get called properly.
Like so:
LinkButton lb = new LinkButton();
lb.click += new EventHandler(lb_Click);
protected void lb_Click(object sender, EventArgs e)
{
LinkButton lb2 = new LinkButton();
lb2.click += new EventHandler(lb2_Click);
}
protected void lb2_Click(object sender, EventArgs e)
{
//do something
}
Hope this helps some future visitors :)

Accessing dynamically generated controls Object reference not set to an instance of an object

I am adding controls dynamically to my page on the basis on a condition.There's a button in these controls, to which i have attached an event handler as well for click event.Now in this event handler, i am trying to access my dynamically generated controls, but getting an exception. Here's my code:
protected void Page_Load(object sender, EventArgs e)
{
String Method = Request.QueryString["Method"];
String Tag = Request.QueryString["Tag"];
if (Method=="ADD" && Tag=="METHOD")
{
//6
TableCell cell11 = new TableCell();
cell11.Text = "NEXTLEVEL";
TableCell cell12 = new TableCell();
TextBox txt6 = new TextBox();
txt6.ID = "txt6";
cell12.Controls.Add(txt6);
TableRow row6 = new TableRow();
row6.Cells.Add(cell11);
row6.Cells.Add(cell12);
container.Rows.Add(row6);
TableCell cell14 = new TableCell();
Button submit = new Button();
submit.ID = "SubmitButton";
submit.Text = "Submit";
submit.Click += new EventHandler(submit_Click);
cell14.Controls.Add(submit);
TableRow row7 = new TableRow();
row7.Cells.Add(cell14);
container.Rows.Add(row7);
}
void submit_Click(object sender, EventArgs e)
{
ModifySessionAnalyzer msa = new ModifySessionAnalyzer();
TextBox txt6= (TextBox)Page.FindControl("txt6") as TextBox;
##String message = txt6.Text;##
}
TableCell cell12 = new TableCell();
TextBox txt6 = new TextBox();
txt6.ID = "txt6";
cell12.Controls.Add(new TextBox());
This is wrong, you are not adding the txt6 control to the cell, instead you are adding a new textBox...
Dynamically added controls should be added in the Page_Init method not Page_Load. If they are added into Page_Load they won't be added to the control tree and you'll get issues - i.e. they won't participate in ViewState correctly.
So (TextBox)Page.FindControl("txt6") could fail as the text box is no longer in the control tree
This could be the source of your issue.
Further explanation
Your code should be
protected void Page_Init(object sender, EventArgs e)
{
//.. your code goes here
}
NOT
protected void Page_Load(object sender, EventArgs e)
{
//.. your code
}
It's normal practice to use Page_Load so it's just an easy habit for people but when using dynamic controls then this is the exception
When i say dynamic controls - it's anything when you are added controls on the fly rather than declaring them in your page. Look for anything where you are going Controls.Add

asp.net get the text from a dynamically inserted textbox return null all the time

I am writing a web app in asp.net, in one of my aspx pages I have a static table.
To this table I insert a dynamically textbox control from the code behind (from Page_Load, I create this control dynamically because I do not know if I need to create it or not it depend on a user answer), the problem is when i try to get the textbox text after the user click on a button, I tried every thing i know from Request.Form.Get("id of the control") to Page.FindControl("id of the control"), but nothing works I get null all the time, just to be clear the button that activate the function that get the text from the textbox is insert dynamically to.
Both button and textbox are "sitting" in a table and must remain so, I'd appreciate any help
my code is:
aspx page
<asp:Table ID="TabelMessages" runat="server"></asp:Table>
code behind aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
TextBox tb = new TextBox();
tb.ID = "textBox";
tb.Text = "hello world";
TableCell tc = new TableCell();
tc.Controls.Add(tb);
TableRow tr = new TableRow();
tr.Cells.Add(tc);
TabelMessages.Rows.Add(tr);
}
public void Button_Click(object o, EventArgs e)
{
string a = Request.Form.Get("textBox");//does not work
Control aa = Page.FindControl("textBox");//does not work
}
in your
public void Button_Click(object o, EventArgs e)
{
//try searching in the TableMessage.Controls()
}
Alternatively, and depending on what you ultimately want to do, and still use Page_Load:
In your Page Class:
protected TextBox _tb; //this is what makes it work...
protected void Page_Load(object sender, EventArgs e)
{
_tb = new TextBox();
_tb.ID = "textBox";
TableCell tc = new TableCell();
tc.Controls.Add(_tb);
TableRow tr = new TableRow();
tr.Cells.Add(tc);
TabelMessages.Rows.Add(tr);
if (!Page.IsPostBack)
{
_tb.Text = "hello world";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = _tb.Text; //this will display the text in the TextBox
}
You need to run your code inside the Page_PreInit method. This is where you need to add / re-add any dynamically created controls in order for them to function properly.
See more information about these types of issues in the MSDN article on the ASP.NET Page Life Cycle.
Try changing your Page_Load code to the following:
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
TextBox tb = new TextBox();
tb.ID = "textBox";
tb.Text = "hello world";
TableCell tc = new TableCell();
tc.Controls.Add(tb);
TableRow tr = new TableRow();
tr.Cells.Add(tc);
TabelMessages.Rows.Add(tr);
}

When does a page get rendered in ASP.NET?

I'm writing am ASP.NET/C# project, it's a simple blog page with commnents.
Problem I'm having when button click you see comments load original blogload plus blogs and comments, trying to get it to load blog/comment selected only.
If I try not to load blog in page_load or have it only do if not postback nothing is displayed. Any help would be appreciated.
PS I know there are many blog engines out there but have specific reason.
protected void Page_Init(object sender, EventArgs e)
{
//ParseControls(GlobalVar.pathxsltver);
// BindInfo();
}
private void ParseControls(string myxslt)
{
//load the data
FileStream fs = new FileStream(Server.MapPath ( GlobalVar.compathver), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
DataSet dset = new DataSet();
dset.ReadXml(fs);
fs.Close();
XPathDocument xdoc = new XPathDocument(Server.MapPath(GlobalVar.pathver ));
XmlDocument mydoc = new XmlDocument();
XPathNavigator navigator = xdoc.CreateNavigator();
XPathExpression expression = navigator.Compile("BlogItems/Blog");
expression.AddSort("ID", XmlSortOrder.Descending, XmlCaseOrder.UpperFirst, string.Empty, XmlDataType.Text);
XPathNodeIterator iterator = navigator.Select(expression);
int TheCnt = 0;
int cnt = GlobalVar.BlogCntDisplay;
string st = "<BlogItems>";
foreach (XPathNavigator item in iterator)
{
TheCnt++;
string sid = item.SelectSingleNode("ID").Value;
st = st + "<Blog id=\"" + sid + "\">" + item.InnerXml;
st = st + "<ComCnt>" + MyFunc.CountComments (sid,dset) + "</ComCnt></Blog>";
if (TheCnt == cnt) { break; }
}
st = st + "</BlogItems>";
mydoc.LoadXml(st);
XslCompiledTransform transform = new XslCompiledTransform();
XsltSettings settings = new XsltSettings(true,true);
transform.Load(Server.MapPath(myxslt),settings,null);
StringWriter sw = new StringWriter();
transform.Transform(mydoc, null, sw);
string result = sw.ToString();
//remove namespace
result = result.Replace("xmlns:asp=\"remove\"", "");
//parse control
Control ctrl = Page.ParseControl(result);
//find control to add event handler
//Boolean test = phBlog.FindControl("btnComment2").i;
phBlog.Controls.Add(ctrl);
XmlNodeList nList = mydoc.SelectNodes("//BlogItems/Blog/ID");
foreach (XmlNode objNode in nList)
{
Button btnComment = (Button) phBlog.FindControl("btnComment"+objNode.InnerText );
btnComment.CommandArgument = objNode.InnerText ;
btnComment.BorderWidth = 0 ;
btnComment.Command += new CommandEventHandler(Button1_Click);
}
}
protected void Page_Load(object sender, EventArgs e)
{
//if (!Page.IsPostBack )
//{ParseControls(GlobalVar.pathxsltver);}
ParseControls(GlobalVar.pathxsltver);
}
protected void Button1_Click(object sender, CommandEventArgs e)
{
Label1.Text = "Comm hit : " + e.CommandArgument.ToString();
ParseControls(GlobalVar.blogcommentsver );
}
You're question is kind of vague, but if I understand you correctly, you're wondering why the entire page refreshes when you just want to handle the button click?
Whenever you do any kind of postback, and that includes handling any events, the entire page is re-rendered. More than that, you're working with a brand new instance of your page class. The old one is dead and gone. That's just the way the web normally works.
If you only want to reload a part of the page, you need to use ajax. In ASP.Net land, that means placing your comments section inside an UpdatePanel control that can be refreshed.

Resources