I have a problem with a Dev Express component, namely AspxComboBox.
My context is this: I want to dynamically generate the interface for some of my business entities. I have designed a user-control that receives some metadata and, based on that metadata, the controls adds text boxes, date-editors and combo boxes to the interface. All of those controls work like a charm when they are added to the page in a non-dynamic manner.
However, when I add them from the C# code, the following Javascript line has an error:
document.getElementById("usercontrol_combo_I").setAttribute("autocomplete", "off");
"usercontrol" is the ID of the user control I'm designing. "combo" is the ID of the combo.
The error is that the element with the ID ("usercontrol_combo_I") is not to be found in the HTML DOM.
I've discovered that if I choose not to use DataBind on the combo itself (comment out any call to the DataBind() method of the AspxComboBox instance), the JS line that has the error is never rendered (is not present in the final HTML). But, if I leave it like that, any subsequent PostBacks empties the combo list (there are no more items in the combo). The datasource of the combo is a IList instance that is assigned on every page load (even if PostBack == true).
There is a post on DevExpress's support forum that reports the same problem, but, there is no answer from the team.
Anybody here had this problem and found a way to solve it?
With ASP.NET Dev if you're binding on the Page_Load events, you need to bind in ALL requests back to the server, this includes Callbacks as well.
Now getting the HTML element and setting its attributes isn't supported. The only supported way to turn autoComplete off is for a callback to be sent to the server and turn off autoComplete on the server-side property which will update the control. Now the comboBox MUST be the one to perform the callback or wrap the box in a CallbackPanel.
Are you setting the ClientInstanceName of the ASPxComboBox too?
Actually, I've just found a simple workaround.
If I just call DataBind() on my generated control in the page_load event of the page itself, the problem is gone.
For example:
protected void Page_Load(object sender, EventArgs e)
{
base.Page_Load();
this.control.DataBind();
}
Where "control" is a UserControl that contains the combobox.
The weird thing is that I call DataBind even on PostBack and CallBack.
But, hey, it works.
I suppose that there are still a couple more things that I miss when using Devexpress.
But "practice makes perfect" !
Thanks for the reply.
Related
As the title suggests, we are having issues getting the correct text value of a Textbox after a post back.
Context:
The Textbox is called textbox_registration
The Textbox is in a dynamically loaded control.
The dynamic control is recreated every post back and has its data set in the OnInit event.
The dynamic controls are within a PlaceHolder inside an UpdatePanel.
It is expected that the value posted in the form will then be present in the Text property of the Textbox. The first form submission is fine, then it gets weird. The UniqueID of textbox_registration changes in every subsequent submission, breaking the expected value stored in the Text property. The following is an example of the UniqueIDs of the Textbox.
ctl00$CollapsableSidebar$panel_editAsset$ctl01$textbox_registration
ctl00$CollapsableSidebar$panel_editAsset$ctl02$textbox_registration
My theory is that when the dynamic control it loaded in init again it avoids a collision with the previous instance of the Textbox by changing the generated UniqueID, then when the second post back occurs the ID has to be different, and thus corrupting the ViewState initialisation between the init and load methods.
This is very irritating, because looking in the Request.Form collection I can see the correctly posted value.
How can I retrieve the posted value for textbox_registration.Text?
Edit 1:
Just to clarify textbox_registration is a normal static ASP Textbox within a UserControl that we have loaded dynamically.
Edit 2:
To outline the scenario, the source code has been stripped down to the following files:
Item Page, a page to display items.
Edit Pane, a custom UserControl on the Item Page that is used to load the dynamic controls.
Dynamic Control, an example of a dynamic item editing control loaded into the Edit Pane.
IEditItemPanel, an interface that the edit controls must implement.
Try setting ClientIDMode property when you create your TextBox control
textbox_registration.ClientIDMode = ClientIDMode.Static;
Then when you want to retrieve the text
var textBox = (TextBox)this.Form.FindControl("textbox_registration");
var textBoxText = textBox.Text;
After investigating the issue, it was a logical error causing the issue.
Because the edit control was loaded dynamically it was important that the control was loaded for post backs by the end of OnInit or up to OnLoad as long as the item was loaded in the control before Controls.Add() was called.
With this knowledge, the OnInit event was investigated closely in the dynamic control. It was being called twice on the post backs! A logic error! This caused the controls to be created twice and the posted form values corresponded to the controls created in the first OnInit call. Therefore, the second OnInit call generated different UniqueIDs for the controls. When the ViewState was restored the controls did not exist.
The solution was to make sure the control is created properly every post back like the first time it is created. The first time didn't make a duplicate control, so neither should the second!
Turns out a look back at the 'Dynamic Controls Basics 101' was needed.
This link 'Dynamic Controls Made Easy in ASP.Net' finally made the solution click into focus.
EDIT: I needed to skip control creation during post back -- see my answer below.
I'm working on a very basic front end to a simple tool and I wanted to present some data in a much more sorted and useful way, instead of making one huge wall of text. I found this tutorial on building a simple tabbed interface using MultiView, but have run into a bizarre problem. I can't use Ajax tabs because of legal hissy fits over 3rd party software.
My webpage is a basic ASP.NET page with a user control plopped in the middle of it. In this control's ascx file, I defined the Menu (empty) and the MultiView (also empty) so that I can dynamically populate the tabs with content driven from an external file.
When the default page's OnInitComplete function is called, I call through to the user control to load the data file, then build out the tabs and the view content based on the loaded data. I tried doing this from PageLoad, PreInit, and CreateChildControls, but I kept getting an errors saying that I was setting the the MultiView's active view index at an invalid time (and also that there were 0 views despite the fact I just added a bunch of them):
ActiveViewIndex is being set to '0'. It must be smaller than the
current number of View controls '0'. For dynamically added views, make
sure they are added before or in Page_PreInit event.
But OnInitComplete appears to work just fine, so I went with that.
I iterate over the loaded data (multiple lists of strings), and for each list, I add a MenuItem with the list's title to the Menu and a View to the MultiView. The View is populated with a table->row->cell as in the above tutorial. In the cell, I add the list title and a CheckBoxList data bound to the list of strings.
So far so good, but when I click on a tab (or one of the checkboxes, etc) and there is a postback or something like that (the screen flashes as the site redraws itself), there is now a duplicate set of MenuItems immediately after the original. Each time I click on a tab or checkbox, another set of menu items are added.
I clear the MenuItem's Items list prior to building the controls and I verify that the controls hierarchy is structurally as expected after the control construction. Yet when one of my callbacks is called, my MenuItem list magically has some items added to it. None of my other controls appear affected at all. As a hack, I can remove the duplicates manually in my menu's OnMenuItemClick event, but I'd have to do the same in any of the callbacks I receive. Obviously I'd rather prevent this from happening. This has me stumped and I haven't been able to find anything online about it. Why would one set of controls have some content duplicated, yet every other control maintain its state correctly? My code is really simple so there isn't a way to add additional menu items without also adding the views. Anyway, there are a correct number of items prior to clicking on the tab/checkbox, an additional set immediately following in the callback.
This is my first time using ASP.NET, so I'm learning as I go. :) Thanks!
My problem was that I was not testing for postback before creating the controls. The code below is working for me.
In my user control's code behind:
protected void OnInitComplete( EventArgs e )
{
if( !Page.IsPostBack )
{
CreateMyControls();
}
}
I have an existing ASP.NET 3.5 application with a webform containing a FormView control used to perform CRUD operations on a domain object. A new requirement adds some dynamic content to the domain object that needs to be reflected in the FormView. This means that I need to generate those controls on-the-fly based on the bound object.
I am using an ObjectDataSource for the FormView that returns the domain object for binding. The domain object will now have a property that returns a collection of Section objects with each Section containing a list of Questions. In the middle of my form, I need to display each section with the list of questions and a textbox that allows the user to input the answer.
I am able to generate the UI a number of different ways but I have yet to find a way that includes data for the dynamic fields when the page is posted back. Because I won't know the 'schema' until the FormView is data-bound, I'm wondering if I'm too late in the pipeline for postback data to be handled properly.
What is the best way for me to generate these fields so the data is posted back correctly?
UPDATE
I'm still looking for the best way to accomplish this task but I've found a solution that at least works. In short, I am creating the dynamic content in the FormView's DataBound event handler because this is the first place in the pipeline that I can always get references to the FormView's controls. Then I follow Muhammed's suggestion and pull the values right out of the Request.Form collection and put them into the EventArgs objects in the FormView's ItemInserting and ItemUpdating handlers.
This isn't so straight forward as each control has to have a unique ID that I can then use to locate the value - which isn't so bad. However, I had to implement custom logic in the data source to then map these values into the data-bound object.
All-in-all, not too bad but certainly not something I'd want to duplicate in other solutions so I'm hoping there's still a better way.
When you want to get the value from the dynamic generated field, you should get it from the Request.Form collection and pass it into the ItemInserting event of FormView. e.g.
protected void frmAsset_ItemInserting(object sender, FormViewInsertEventArgs e)
{
e.Values["FieldName"] = Request.Form[ControlClientID];
}
Please note, your controls should be recreated on postback to get the value.
I have a main page into which i load a user control with a grid and add/edit link buttons.
If I bind the grid by setting the datasource and calling the databind() method in the page load event then it sets properly. However, I want to keep the selected row between postbacks, so I wrap the bind code in "if (!Page.IsPostBack) {}" as usual. My problem is the page load always registers it as a postback and my code never runs.
I am using the 2.0 framework, and my grid is an 2008.1 Infragistics for the 2.0 framework.
I thinking this must be something simple.... or hoping anyway!
Thanks in advance
If you place your control into an UpdatePanel, then you should check for Page.IsCallback instead of Page.IsPostBack.
The two ways I found round this were:
to load the user controls when the page is first loaded and then hide them until user selected what they need to see.
to load a new page into an iframe on the main page allowing it to have its own page control meaning when its loaded in at first its not a postback.
Not the greatest, but gets by.
Thanks for the help.
I have mixed feelings about necroing a thread this old, but the question is still relevant, and there weren't any great solutions offered, so though I would add what I recently did to solve the same issue:
I had a similar problem with a site I was building. My solution was to add a method to the user control called "OnFirstLoad" that does all of the stuff I would have wrapped in an "if not Page.IsPostback" block. I then call the "OnFirstLoad" method from the hosting page the first time the control is loaded into the control tree. This way the control itself doesn't have to worry about whether or not this is a postback, and the main page can initialize it as needed.
I have several "ASP:TextBox" controls on a form (about 20).
When the form loads, the text boxes are populated from a database.
The user can change the populated values, and when they submit the form, I take the values posted to the server and conditionally save them (determined by some business logic).
All but 1 of the text boxes work as intended.
The odd box out, upon postback, does not contain the updated value that the user typed into the box.
When debugging the application, it is clear that myTextBox.Text reflects the old, pre-populated value, not the new, user-supplied value.
Every other box properly shows their respective user-supplied values.
I did find a workaround.
My solution was to basically extract the text box's value out of the Request.Form object: Request.Form[myTextBox.UniqueID], which does contain the user-supplied value.
What could be going on, here?
As I mentioned, the other text boxes receive the user-supplied values just fine, and this particular problematic text box doesn't have any logic associated to it -- it just takes the value and saves it.
The main difference between this text box and the others is that this is a multi-line box (for inputting notes), which I believe is rendered as an HTML "textarea" tag instead of an "input" tag in ASP.NET.
Are you initially loading the data only when !Page.IsPostBack? Also, is view state enabled for the text box?
this happens to me all the time.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// populate text boxes from database
}
}
I would second Jonathan's response I would check your databinding settings.
If you do not need ViewState for the textboxes (i.e. no postback occurs until form submit) then you should disable it.
It sounds like you are not having problems saving the data (since you said you have managed to get the control to read the correct data back). Therefore, I would say the problem loads in your databinding code.
Remember the order of the page lifecycle, and where you are databinding your form.
PreInit
Init
Load
Your Control Event Handler
If you are reading the value in the Control Event handler, yet databinding in Init or Load, you'll have the old value.
The trick is to always databind in the correct event, or check for postback and don't databind then.
Are you initially loading the data only when !Page.IsPostBack? Also, is view state enabled for the text box?
I had almost forgotten to check the ViewState, but ended up remembering to verify that it wasn't disabled before making my post here on SO. I even set EnableViewState="true" to make sure.
I did find the solution, and it coincided with most of the answers here. The form was indeed loading its data more than once (which is intentional behavior). I implemented some special code for this field, and all is well.
Thanks for your replies, all!