I'm creating a custom script control in ASP.NET
The purpose of the control is simply a server variant of the tag, used to load javascript files
The main purpose of this control however is to combine multiple scripts into one response so on the client side they see something like
tag for each location, so all scripts registered in the DocumentTop location will be combined into a single tag with the exception of the location "inline", all inline scripts are rendered individually where they exist in the markup
I have also created an httphandler, js.ashx, that does the actual combining of the scripts
Everything is working fine except for the "Head" location, for the two document locations i simply use the ClientScriptManager during prerender but for the Head location i have tried the following code during pre render
var scriptControl = new HtmlGenericControl("script");
scriptControl.Attributes["language"] = "javascript";
scriptControl.Attributes["type"] = "text/javascript";
scriptControl.Attributes["src"] = src;
Page.Header.Controls.Add(scriptControl);
and I get the following error:
The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.
does anyone know how add a control to the page header from within a custom control?
Incidentally, the control is used on a content page that has two nested masters and also has a ScriptManager registered on the root master.
The project is an asp.net 3.5 web application project
Ive discovered an answer to my question.
I don't quite understand the why but the problem lies in when I am trying to add my script control into the head, doing it in the control's PreRender event causes my error but if you add the control during the Page's PreRender event it all works fine and dandy
eg:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.Page.PreRender += new EventHandler(Page_PreRender);
}
void Page_PreRender(object sender, EventArgs e)
{
var scriptControl = new HtmlGenericControl("script");
Page.Header.Controls.Add(scriptControl);
scriptControl.Attributes["language"] = "javascript";
scriptControl.Attributes["type"] = "text/javascript";
scriptControl.Attributes["src"] = "blah.js";
}
I don't know why you get this error but how about using ClientScript like that :
protected void Page_Load(object sender, EventArgs e)
{
string scriptFile = "myscriptFile.js";
if (!this.Page.ClientScript.IsClientScriptIncludeRegistered("myScript"))
{
this.Page.ClientScript.RegisterClientScriptInclude("myScript", scriptFile);
}
}
ClientScriptManager.RegisterClientScriptInclude Method
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlGenericControl js = new HtmlGenericControl("script");
js.Attributes["type"] = "text/javascript";
js.Attributes["src"] = yol.ScriptYol("jquery-1.3.2.min.js");
this.Page.Header.Controls.Add(js);
}
Related
I have a WebView that I navigate to a URL, and I want to read the contents, Interact with the JavaScript, etc.
I tried
XAML:
<WebView Name="wv1" LoadCompleted="wv1_LoadCompleted" />
C# code:
private void wv1_LoadCompleted(object sender, NavigationEventArgs e)
{
var uri = e.Uri;
var c = e.Content;
}
The problem is that the e.Uri is returned, but the e.Content is null.
How to access the DOM?
How can I do that?
The problem is that the e.Uri is returned, but the e.Content is null.
The Content property of NavigationEventArgs is used to get the root node of the target page's content. The page is xaml page but not web page. You could verify it with Frame.Navigated event. When page navigated you could get value of Content.
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Content.ToString());
}
If you want to get the web page content. you could refer this reply. With some updates:
To enable an external web page to fire the ScriptNotify event when calling window.external.notify, you must include the page's Uniform Resource Identifier (URI) in the ApplicationContentUriRules section of the app manifest.
The follow eval method used to get body html.
string functionString = #"window.external.notify(document.getElementsByTagName('body')[0].innerHTML)";
await Test.InvokeScriptAsync("eval", new string[] { functionString });
And you could get the return value form ScriptNotify event handler.
private void Test_ScriptNotify(object sender, NotifyEventArgs e)
{
var body = e.Value;
}
In my javascript file, I got an ajax to get all list and iterate these data and append <a id='userID' class='btn'>Assign ID<> to my list.
So, how do a add postback to these anchor and redirect it inside my method in the server. Below is my code but didn't work. When I click the achor button, it just redirect/refresh to the same page without doing any changes and didn't show the text.
<a id='uniqueID' class='btn assignID' href='javascript:void(0);' onclick='javascript:__doPostBack('uniqueID','')'>Assign ID</a>
protected void Action_assignID(object sender, EventArgs e)
{
// assign ID action
Response.Write("Pass");
}
You should be changed your button to:
<a id='uniqueID' class='btn assignID' href='javascript:void(0);' onclick="javascript:__doPostBack('uniqueID','Assign ID')">Assign ID</a>
And it's a good idea to implement the IPostBackEventHandler interface in your codebehind as below:
public partial class WebForm : Page, IPostBackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
}
}
public void RaisePostBackEvent(string eventArgument)
{
// do somethings at here
}
}
Hope this help!
The __doPostBack method really doesn't do anything special except, well... perform a POST operation back to the same page with two specific form arguments.
The first parameter is the __EVENTTARGET and the second parameter is the __EVENTARGUMENT.
The magic all happens in ASP.Net where it automagically wires up your controls to event handlers, but since you are creating these entirely in JavaScript the server doesn't know that those controls exist.
However, you can manually grab these values and do something with them.
//Client Side JavaScript:
__doPostBack('my-event', '42');
//Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
var target = Request.Params["__EVENTTARGET"];
var args = Request.Params["__EVENTARGUMENT"];
Target.Text = target; // 'my-event'
Argument.Text = args; // '42'
}
}
I have a web form which dynamically loads controls upon selection in combobox(devexpress). I have the following code on main form
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
if (Session["_active_control"] != null)//persist control on postbacks
{
Control cntrl = Session["_active_control"] as Control;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
protected void cmb_control_SelectedIndexChanged(object sender, EventArgs e)
{
Control cntrl= Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
Session["_active_control"] = cntrl;
}
also I have a user control having three Textboxes and a button having code
protected void btn_save_Click(object sender, EventArgs e)
{
lbl.Text = ASPxTextBox1.Text + "<br>" + ASPxTextBox2.Text + "<br>" + ASPxTextBox3.Text;
}
My problem is that the save button of user control is not firing if i load it dynamically (I have checked using breakpoints and also the code shown above. however it runs smoothly if I use it statically.(i.e. by dragging in design mode)
You are right that you have to persist the control across postbacks.
However the Page Load event is too late to add back your controls. Do this on the Init event of your page and you should be good. To receive a postback event, the control should be present when ProcessPostData(called before PreLoad) is called.
Also for textboxes you will want to receive the values entered by the user. This too happens on ProcessPostData, if you add you control after that, you will not receive the values entered by the user.
Refer: ASP.NET Page Life Cycle
hey i found the solution
instead on creating the controls in combobox_selectedindexchanged i put my control creation code on Pageload based in combobox.selectedindex i.e.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (cmb_control.SelectedItem != null)
{
Control cntrl = Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
cntrl.ID = "_new_ctrl" + cmb_control.SelectedItem.Value;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
see Button click event not firing within use control in ASP .Net
After adding a control in the dayrender event, is there a way to find the control later? I have tried
calendar.FindControl("lblSample")
but without success.
Here is some of my code to be more clear:
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
Label lblSample = new Label();
lblSample.ID = "lblSample";
lblSample.Text = "Sample";
e.Cell.Controls.Add(lblSample);
}
After the day render event and the page loads completely, I have a link button event where I try and get the control back
protected void lbtnSave_Click(object sender, EventArgs e)
{
//Not working
Label lblSample = calSample.FindControl(lblSample);
//Also can't get to work, this was using Ross' suggestion and the recursive find function he wrote about. I'm probably just not using it correctly.
Label lblSample = ControlFinder.FindControl<Label>(calSample, "lblSample");
}
The issue was because the control was not added to the page until the dayrender method - meaning you could not get a reference to it on a post back. Using the Page.Request.Params collection the OP was able to grab the value out on the postback.
The problem is that the find control is not recursive and the control you want is probably inside another control.
This shows you how to make a recursive find control method that would help: http://stevesmithblog.com/blog/recursive-findcontrol/
Alternatively if you post the calendar controls code I can probably help you a bit more.
Ross
This answer is because of Ross' comment above showing me that I could use the Page.Request.Params to find the value I was after. It's not the cleanest solution but it works!
If you add a dropdownlist to a calendar control in the day render event
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
DropDownList ddlSample = new DropDownList();
ddlSample.ID = "ddlSample";
ddlSample.DataSource = sampleDS;
ddlSample.DataBind();
e.Cell.Controls.Add(ddlSample);
}
You can get the selected value back like this, of course I need to put in more checks to verify that the dropdownlist exists, but you get the picture
protected void lbtnSave_Click(object sender, EventArgs e)
{
string sampleID = Page.Request.Params.GetValues("ddlSample")[0];
}
I have a an ASPX Page with a Placeholder control declared.
In the Codebehind I create a UserControl I have and add it to the Placeholder.
protected void Page_Load(object sender, EventArgs e)
{
UserControl uc = new ChartUserControl();
myForm.Controls.Add(uc);
}
The UserControl in turn has a Placeholder, but in the Page_Load (for the UserControl) when I do:
protected void Page_Load(object sender, EventArgs e)
{
WebControl x = new WebControl();
userControlPlaceholder.Controls.Add(x);
}
It gives me the ubiquitous "Object reference not set to an instance of an object" exception.
I've tried forcing instantiation by calling a constructor, but that has gotten me into other trouble. Any help would be appreciated.
I just spent 4 hours on this myself.
The problem is that you're creating the user controls with
ChartUserControl chart = new ChartUserControl();
but you have to use LoadControl:
ChartUserControl chart =
(ChartUserControl)LoadControl("~/path/to/control/ChartUserControl.ascx");
Apparently, LoadControl initializes the user control so that its PlaceHolders (and I would assume, other controls it contains), won't be null when you use them.
Instead of adding the control in the Page_Load, Override the CreateChildControls method and add it there.