I'm trying to get the values of dynamically generated FileUpload controls that I add to a Panel:
<asp:Panel ID="pFileControls" runat="server">
</asp:Panel>
I create the controls during a loop through a record set:
foreach(DataRow dr in ds.Tables[0].Rows)
{
FileUpload fu = new FileUpload();
fu.ID = dr["SomeID"].ToString();
pFileControls.Controls.Add(fu);
}
Everything works fine up to the point where I submit the form with this button:
<asp:Button ID="btnImportFile" runat="server" Text="Save" OnClick="btnImportFile_Click" />
Which I register like this (Page_Load):
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnImportFile);
I do this because I'm using a MasterPage/ContentPage setting in my website and mostly everything happens inside an UpdatePanel for AJAXification purposes. Bear in mind that if I explicity specify a FileUpload Control in the HTML view, it works 100%.
When the form is submitted I try to iterate the Panel like this:
foreach (Control ctrl in pFileControls.Controls)
{
if (ctrl.GetType() != typeof(FileUpload))
{
continue;
}
//Do the saving of the file here
}
Except, the Panel seems to only return one control: The Content Place Holder for the page and nothing else. Does anyone have some ideas about this?
What part of the life cycle are you adding the dynamic controls?
if you are putting them in the page_load it may be too late, try putting the generation of the dynamic controls into the page_init and see if that fixes the problem.
page lifecycle
http://msdn.microsoft.com/en-us/library/ms178472.aspx
dynamic controls
http://geekswithblogs.net/shahed/archive/2008/06/26/123391.aspx
Note:
"Its recommended to load the dynamic
controls during the Page_Init instead,
because we may want to hook up our
events with proper handler at an early
stage. ... Do not assigning
properties of a dynamic control
(viewstate enabled), during Page_Init,
it will not be reflected. "
I would expect that even with the update panel, you will need to be mindful of the page_load limitations with dynamic controls.
let me know if this helps or if I missed the mark!
Let's try a different course of action (I've gotten dynamic file upload to work, but it was a bear and I wish I had simply used this)
http://www.asp.net/ajaxlibrary/act_AsyncFileUpload.ashx
or
http://en.fileuploadajax.subgurim.net/
these may not create a 'loop' of elements, but you can simply keep loading docs on a as-needed basis.
I have specifically used
http://www.asp.net/ajaxlibrary/act_AsyncFileUpload.ashx
to great effect.
There also appear to be some limitations to the update:panel and the file upload, check out these sites.
(this one says it does not work in partial update status but does work in full postback)
http://forums.asp.net/p/1105208/1689084.aspx
do you know if the submit is triggering the full page or just the update:panel? (check out this: http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx
Related
I needed a tree view that has checkboxes, asynchronously gets data to populate the nodes when they are expanded, and automatically checks/unchecks child/parent nodes appropriately as checkboxes are clicked.
The only part that didn't work out of the box was the checking/unchecking of child/parent nodes when their children/parent nodes are clicked. While there is an event available for when a checkbox is clicked, it doesn't automatically post back so I added some javascript to make it do so.
It was working really well when I was getting data directly from the control, but when I decided to refactor the control so I could use it in other places I decided to create an event that consuming code would assign to in order to provide the control a way to get data from the right place.
I assign to my event on the Page_Load of the page the control is on, and this works for expanding nodes just fine because the event gets assigned to again at the beginning of each post back. However, when I click a checkbox the Page_Load event for the page the control is on doesn't get called and so the event doesn't get assigned to.
I've already planned to implement an alternate solution that will use jQuery to do the checking/unchecking on the client side without posting back, but I'd really like to know the proper design pattern for handling this kind of situation.
Below is the aspx that shows how I'm making it post back. I can post other code if needed or if my explanation wasn't clear.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="DepartmentTreeView.ascx.cs" Inherits="TrainUp.Web.Lms.Mtv.Controls.RequiredTraining.DepartmentTreeView" %>
<script type="text/javascript">
<%-- This is used to cause a postback when a checkbox is clicked,
which allows the DepartmentTree_TreeNodeCheckChanged event to get raised --%>
function postBackByObject() {
var o = window.event.srcElement;
if (o.tagName == "INPUT" && o.type == "checkbox") {
__doPostBack("", "");
}
}
</script>
<asp:TreeView ID="DepartmentTree" SkinId="Contacts" runat="server"
OnTreeNodePopulate ="DepartmentTree_TreeNodePopulate"
OnTreeNodeCheckChanged="DepartmentTree_TreeNodeCheckChanged"
OnClick="javascript:postBackByObject()" />
Can't add comments yet but it sounds as you aren't putting your code on the right state of the page life cycle to render your treeview again. You can reuse the treeview using a webcontrol or encapsulating all the logic on a js file and referencing it on every page you need to use it.
Actually I don´t see the problem and the code should work just fine. However, I recommend to change your javascript code though because it won´t work in Firefox (window.event.srcElement doesn't work for firefox?)
function postBackByObject(e) {
var evt = e || window.event;
var o = evt.target;
if (o.tagName == "INPUT" && o.type == "checkbox") {
__doPostBack("", "");
}
}
<asp:TreeView ID="DepartmentTree" runat="server" ShowCheckBoxes="All"
ShowExpandCollapse="true"
OnTreeNodePopulate="DepartmentTree_TreeNodePopulate"
OnTreeNodeCheckChanged="DepartmentTree_TreeNodeCheckChanged"
OnClick="postBackByObject(event);" />
I am new to ASP.NET programming.
I would like to add controls to my current page when a button is clicked.
Currently, this is the event that gets fired:
protected void Button_Click(object sender, EventArgs e) {
LiteralControl litctrl = new LiteralControl("<div> Testing " + DateTime.UtcNow.Millisecond +" </div>");
form.Controls.Add(litctrl);
}
This works fine on the first click but if I click again, I do not get an extra div added to the form. A new div is created but the previous one is lost.
Why is it so and how can I create controls additively on the current page ?
See http://chiragrdarji.wordpress.com/2009/05/20/maintain-viewstate-for-dynamic-controls-across-the-postback/ for some examples. Adding dynamic controls in ASP.NET Webforms is a tricky dance between understanding postbacks and the page lifecycle. Throw in any ViewState requirements and it takes some even deeper understanding.
For your requirements, you need to recreate any dynamically added controls on every postback. As you aren't, it disappears.
This technique is often known as adding "Dynamic" controls.
Examples include:
http://www.stev.org/post/2011/03/02/ASPNET-Dynamic-Controls.aspx
https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx
http://weblogs.asp.net/infinitiesloop/archive/2006/08/25/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_.aspx
http://geekswithblogs.net/shahed/archive/2008/06/26/123391.aspx
http://support.microsoft.com/kb/317794
It is also important to understand the ASP.Net Page Lifecycle - when a control is added is often very important.
Common Pitfalls are covered widely, for example:
Control Add PostBack Problem
problems with postbacks events from dynamic controls in ASP.Net
http://www.singingeels.com/Articles/Dynamically_Created_Controls_in_ASPNET.aspx
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
I'm trying to edit a textbox's text in a Page_Load form on an ASP.NET page, but when I try to edit TextBox1.Text it throws a NullReferenceException because the TextBox has not yet been instantiated. Specifically what I'm trying to implement is this: http://www.codeproject.com/KB/user-controls/popupcalendarcontrol.aspx but it is written for an older version of ASP.NET and does not work for me. Is there a way to instantiate the controls at the start of Page_Load? or another event that I can catch on load? With a normal windows form I would call InitializeComponent() in the constructor.
There are absolutely different events you can attach to but it sounds like the page isn't loading the controls properly because they should be available by that point. You can take a look at the ASP.NET Page Life Cycle for more information.
Does the TextBox sit within a bound control, such as a FormView, GridView, DataList, etc? If so, then the control won't exist until after the databinding happens. Once that event happens, you can do something like
DirectCast(myDataList.SelectedRow.FindControl("myTextBox"),
TextBox).Text
I know that I am a bit behind in getting to this question BUT I have found something unusual that I can NOT find documented anywhere. It would appear that IF your page is "under" a Master Page, and IF you refer to ANYTHING on said master page, the controls to your current page are null - EVERYONE of them. I found this out by referencing "Master.Environment" - a public string - during my InitializeCulture method and having the FIRST control on my current (Default.aspx) page be null during Page_Load() - WHATEVER the first control was.
I know I am late but if this can help ANYBODY, I want the word out.
Is this typical behavior of the UpdateProgress for an ASP.Net UpdatePanel? I have an update panel with the UpdateProgress control inside of a user control window on a page.
If I then make the page in the background do some loading and click a button in the user control update panel the UpdateProgress does not show up at all. It's like the UpdatePanels refresh request is not even registered until after the actual page is done doing it's business. It's worth noting that it will show up if nothing is happening in the background.
The functionality I want is what you would expect. I want to loader to show up if it has to wait for anything to get it's refresh done when after the button is clicked.
I know I can get this functionality if I just use jquery ajax with a static web method, but you can't have static web methods inside of a user control. I could have it in the page but it really doesn't belong there. A full-blown wcf wouldn't really be worth it in this case either. I'm trying to compromise with an UpdatePanel but these things always seem to cause me some kind of trouble.
Maybe this is just the way it works?
Edit:So I'll clarify a bit what I'm doing.
What's happening is I have a page and all it has on it are some tools on the side and a big map. When the page initially loads it takes some time to load the map. Now if while it's loading I open up the tool (a user control) that has the update panel in question in it and click the button on this user control that should refresh the update panel with new data and show the loading sign (in the updateprogress) then the UpdateProgress loading image does not show up. However, the code run by the button click does run after the page is done loading (as expected) and The UpdateProgress will show up if nothing on the page containing the user control is loading.
I just want the loader to show up while the page is loading.
I thought my problem was that perhaps the map loading is in an update panel and my UpdateProgress was only being associated with the update panel for the user control's update panel. Hence, I would get no loading icon when the map was loading. This is not the case though.
I'm not completely following exactly what you're doing here, but I'm assuming you've taken what's in your user control and verified that it works correctly if placed directly in the page?
As a side note, I'm personally ripping out UpdatePanels and replacing with jQuery replacements due to the significant performance savings in addition to the fact that it's way more time-effective to figuring out jQuery et al. quirks instead of ASP.NET AJAX quirks. To be honest, I wish I could claw back the time I did invest in UpdatePanels/ASP.NET AJAX.
I believe I understand your issue after reading your OP several times. I have run into this situation myself with difficulty getting an UpdateProgress to work on Page_Load. The solution? Don't fire the server-side event initially on Page_Load. Add an AJAX Timer that is inside an UpdatePanel like below:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Timer ID="ajxTmr1" runat="server" Interval="1000" OnTick="ajxTmr1_Tick" />
</ContentTemplate>
</asp:UpdatePanel>
The on the timer tick event, do your server code as required. If you have an Update Progress wired up to the UpdatePanel above, everything should work properly.
<asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="0" AssociatedUpdatePanelID="UpdatePanel1" Visible="false">
<%--Panel or whatever goes here--%>
</asp:UpdateProgress>
From what I've already read this appears to be impossible, but I wanted to see if anyone out there has a secret trick up their sleeve or at least a definitive "no".
Supposedly a master page is really just a control for a content page to use, not actually the "master" of a content page. If I wanted to go from one content page, to another content page with the same master page, I would just say
Response.Redirect("PageB.aspx");
But this would immediately cause a postback, flickering the page, which is the crappy pre-ajax way of doing things.
In this current project, I'm trying to see if I could figure out how to change the current content page of a ContentPlaceHolder in the master page asynchronously, when a button is clicked on the master page.
Is this possible, if so how?
I don't know if you can between pages (.aspx) but it can definitely be done using UserControls.
ASP.Net pages each have their own URL so what you're trying to do is to go from one URL to another without any postback, that's just not how it's supposed to work.
Using user controls (.ascx):
Create a page that uses the MasterPage and use something like this in the content
<ajax:UpdatePanel ...>
<ContentTemplate>
<asp:PlaceHolder ...>
</ContentTemplate>
</ajax:UpdatePanel>
Search for UpdatePanel and tweak its settings to do what you want, then learn how to swap user controls in a placeholder.
No, you cannot because a master page is actually a control rendered on a particular aspx page, rather than actually containing the aspx page as it deceptively appears to be programmatically and in design view.
More Info:
You could however use a variety of other controls to simulate this effect. The asp:MultiView control is one example, each "page" could be made in a single view and placed in an update panel, thus allowing it to be switched asynchronously. Alternatively you could define each page in a separate user control and put those in an update panel, asynchronously switching the visible property on those controls as needed.
There are really a lot of different ways to achieve an effect similar to changing the master page's content placeholder.