How to hide a databound control - asp.net

Depending on the case, I'd like to hide a databound control in a page. But no matter what I try, it seems like the control will try biding no matter what. I've tried setting Visible="false", but it would still try to bind. I've tried putting the control into a placeholder and then hide the placeholder, it will try to bind anyway. I've also tried putting it into a MultiView, same thing. You would think that in a wizard interface using a MultiView you would not want the controls in the next steps of the wizard to bind, but no. It binds anyway...
The only way I've found is to unset and set the DataSourceID property which seems to prevent binding.
Is this really the only option?
Thank you.

I think that you are on a good path. Do not set the data source id. When it comes time to display the data (which I presume is triggered by a user click), explicitly databind your control.
when you set the datasourceid on your control, then the asp.net framework will automatically data bind when the page's OnDataBind event occurs.

Could it be that you're using a datasource control to bind to? The DataSourceID property being set indicates so. If you don't want it to bind to such a control you can opt to take out the DataSourceID property in markup and explicitely set it in codebehind only when you need it.

Related

Why does FindControl sometimes find nothing inside a FormView in a UserControl?

I have a FormView in an ASP.NET UserControl. The EditItemTemplate contains some controls, and I'd like to run some code server-side whenever they are created, to set some values based on some conditions.
It appears that the Control.Load and PreRender events are unsuitable for this, since the control can sometimes be rendered without any child controls (not sure why that happens). Specifically, if I look at FormView.ChildControlsCreated in the debugger, I always see True, but when I try to FindControl by name, sometimes it's there and sometimes it isn't.
When should I execute my code that requires access to the inner controls?
This happens because the FormViewMode is sometimes different. There is no template for ReadOnlyMode, so whenever the form is in that mode, FindControl doesn't find anything.

Is it possible to set asp.net control property values in code behind without adding it to viewstate?

I want to assign values to server control properties in my code behind to "initialize" a form. I don't need/want these values to be added to the viewstate. (I know I can disable viewstate for a specific control, but I need viewstate as some values may change and need to be persisted during postbacks.)
At the moment for me it seems its not possible to load these values in code without having them added to the viewstate.
As I understand the following happens:
Page: PreInit
I could add values to SOME controls (its working for example with a literal control to set the text value) here BUT since control's init methods are executed later I cannot for example find a RegisterUser control and its child controls at this stage yet, they are still null. > so no solution in this specific case, there's more cases
Control: Init
I cannot reach this point from within my page, this can only be used inside the user control code for example when you write your own usercontrol and want to initialize its values, I ofcourse dont want to create my own control for each control I need to initialize with executing some logic first.
Control: TrackViewState
Viewstate Tracking is enabled so from here on after anything I set will be marked as 'dirty' and therefore added to the viewstate.
Page:Init
Page:TrackViewState
So am I right in saying:
In code behind, without disabling a controls viewstate property..
You can initialize "1st level" child control properties from the page control in the PreIinit method without having the value being added to the viewstate.
You cannot initialize Child control properties from controls that are "1st level" child controls of the page without having the value added to the viewstate.
?
Then,
You can initialize control properties declaratively by using resources, but this does not circumvent the scenario where you need to execute logic
You can execute logic by using databinding syntax but you would have to manually call databind on the control having the same issues as above
Is there no way to iterate a set of controls/child controls and initiate values in code behind withouth having these values added to the viewstate?
With no reactions here and some further research, I am now at the point to conlude that you can indeed NOT iterate a set of controls/childcontrols and initiate values in code behind without having these values added to the viewstate, because of reasons mentioned in the question.
There are some partial solutions however as made clear here: http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
One possibility is to hook into the init event of the control itself declaratively, you would have to do that for each control. In code behind, inside the event handler you can set the property and since viewstate is not tracking yet it will not be saved in viewstate.
There are more options for different scenario's for example initializing dynamically added child controls inside a custom control by overriding the CreateChildControls method. Definately worth reading the above mentioned 'Truly Understanding Viewstate' link.

Where is the best place to set Visible property of a ButtonField as it does not have OnPreRender?

I am extending the ButtonField DataControlField and I want to set its .Visible property inside this extension.
As it does not have OnPreRender method like other Asp.Net controls, Where is the best place to set .Visible property? Which method? CreateField?
Typically visibility can be set at anytime before the Render event.
Depending on what logic you're trying to implement I'd suggest looking at the ItemDataBound event for whichever data-bound you're working with.
Perhaps if you could be more specific about what you're trying to achieve and why you're setting the visbility I can help further.

ASP.NET DataSource Control "does not have a naming container" exception

I've been getting this exception in my code and wondered if anyone could help me out.
I have a Repeater Control bound to an ObjectDataSource, and the itemtemplate for the repeater contains a User Control (ASCX). This user control in turn contains several other controls, mainly a GridView that is associated with an ObjectDataSource.
On initial use of the controls in this setup, everything works great - data displays properly. However, when I change a filter option (dropdowns outside of the repeater), and then rebind the Repeater, I get the exception:
The ObjectDataSource control 'expDataSource' does not have a naming container. Ensure that the control is added to the page before calling DataBind."
at System.Web.UI.WebControls.DataBoundControlHelper.FindControl(Control control, String controlID)
...
...
at System.Web.UI.WebControls.ObjectDataSource.LoadCompleteEventHandler(Object sender, EventArgs e)
I'm not sure what the problem is - I've read in a few places that moving the datasource outside of the ASCX control might help - this does nothing. The objectdatasource appears to be properly structured, and as I said, it works the first time (only).
I noticed in the stack trace for the exception that this is occurring when ASP.NET is calling FindControl() after LoadComplete() occurs. If I step through my code, it appears as though all my code is finished executing before this happens, so it's all "system" code.
Why would ASP.NET not be able to find this datasource control in the LoadComplete Handler?
Thanks!
Other Notes:
This error occurs every other time. So the first time the data loads properly, then on second refresh fails with this error. Clicking "Load" again, it works (on the third time).
On the times that it fails, it looks like "Page_Load" is being called twice in the ASCX control. So the patterns are:
Working Pattern:
Page_Load on Parent Page
Page_Load on ASCX
Data Loads fine
Failing Pattern:
Page_Load on Parent Page
Page_Load on ASCX
Page_Load on ASCX
Exception
This is all happening from a call to "Repeater.DataBind()", but it behaves differently depending on if it has already been bound or not (evidently).
More Notes:
Real strange behavior. I removed the list of SelectParameters from the bottom of the ObjectDataSource, and all of a sudden, the page does not reject the ObjectDataSource as not having a NamingContainer. Of course, without these parameters, Databinding won't actually work...I can add them in the code, but why would it matter?
Found a strange solution, that I'll post and we can discuss to maybe figure out why this fixed it.
On my page, I had the following structure (paraphrasing the tags somewhat):
Page
DropDownFilter
Repeater
UserControl X
ObjectDataSource
ControlParameters Referencing DropDownFilter
End ObjectDataSource
End UserControl X
End Repeater
End Page
So as you can see, within the Repeater ItemTemplate was the user control, which in turn had the "guilty" ObjectDataSource with ControlParameters. These control parameters had the name of the DropDownList filter on the parent page referenced (so basically, if this control was added to any other page, it would of course fail if it couldn't find a control with the proper name).
So when I went through and changed all the ControlParameters to Parameters (removed the reference to that DropDownList control), now I no longer get the error.
All I can assume is that the fact that this datasource referenced a control on the parent page meant that it was having trouble getting added back to the page's control set on a DataBind(). You would have thought it would fail the first time if it was going to fail at all, so that's still a mystery.
Any thoughts?
This is an exceptional error in ASP.NET DataControls. I had similar problem and lost few months behind this eccentric error, but finally got the solution. The reason is; To display items in ItemTemplate, we should use a server control in the LayoutTemplate to act as the placeholder for the ItemTemplate. For example, we could use a Table/Div control with an ID Property in Layout Template. At run time, this placeholder control will be replaced with the contents of the ItemTemplate and "naming container error" will be disappeared.
Finally, if you are having an objectDataSource in ItemTemplate, make sure that you added somthing(like table/Div) with "Id" property in Layout Template.
Thanks,
Sunil.
Ray hit the nail on the head. You are definitely missing an "if(!IsPostBack)" somewhere. How are you adding the user control to the repeater? Is it dynamic? You say it's in the ItemTemplate, so probably not... But multiple calls to Page_Load imply multiple copies of the control.
Use both DataBind. Example:
SqlDataSource1.DataBind();
ListView1.DataBind();

Which event to do I programatically add validation to a control?

I need to add requiredvalidator on a textbox programatically on a page, do I do that in page_load or some event before that?
That depends on why you need to add it. If it is always going to be there, then OnInit is a good place.
If you need to add it only after an action has occured then you want to do it after LoadViewState has been called so you can continue to add it once you add it the first time. For the first time add, most likely you will want to do it because of some post back event, so you could add it in your event handler.
I would suggest adding a placeholder to the control at the location of where you will want this control. Then you add the control when it is required. You should then store some information in ViewState to know that you added the control. You can then override LoadViewState, and add the control there if it is needed.
If you need the Validator only if the control is loaded with some data, then you add it right after the data has been loaded, be that OnLoad or some property accessor.
Page_Load is good for changing controls' settings.
EDIT :
This code tested and works :
// in page_load event :
validator.ControlToValidate = textboxToValidate.ID;
But if you're generating your validators after an event dynamically, problem might be different.

Resources