I need to remove a control (a textbox) from my page when a certain condition is verified.
Is it possible to do from code-behind or I need to use JavaScript.
NOTE I need to remove the control, not to hide...
Use Controls.Remove or Controls.RemoveAt on the parent ControlCollection.
For example, if you want to remove all TextBoxes from the page's top:
var allTextBoxes = Page.Controls.OfType<TextBox>().ToList();
foreach(TextBox txt in allTextBoxes)
Page.Controls.Remove(txt);
(note that you need to add using System.Linq for Enumerable.OfType)
or if you want to remove a TextBox with a given ID:
TextBox textBox1 = (TextBox)Page.FindControl("TextBox1"); // note that this doesn't work when you use MasterPages
if(textBox1 != null)
Page.Controls.Remove(textBox1);
If you just want to hide it (and remove it from clientside completely), you can also make it invisible:
textBox1.Visible = false;
While you could remove it from the controls collection, why not hide it instead?
yourTextBox.Visible = false;
This will prevent it from being included in the generated html sent to the browser.
When you set .Visible=false, it will never be rendered in the page. If you remove the control from Controls collection, don't do it during DataBind, Init, Load, PreRender or Unload phases as it will throw exception.
Adding or removing control dynamically may result in problems.
Yes, you can just remove it from the controles collection of the page:
this.Controls.Remove(control);
You can try with this code - based on Remove method
this.Controls.Remove(YourControl);
Link : http://msdn.microsoft.com/en-US/library/system.web.ui.controlcollection.remove(v=vs.80).aspx
Related
The problem is simple, I have ids of the contols and i want to show/ hide them on some event.
Actually the problem is i have a direct event on dropdown change i have to hide some controls based on some cases
the code for the direct event is
foreach (Control oControl in ProductConfiguration.Controls)
{
string strName = oControl.GetType().Name;
oControl.Visible = false;
DataRow[] drIRows = dtInfo.Select("ControlId='" + oControl.ID + "' AND ProductGroupId='" + CboProductGroup.Value + "'");
if (drIRows.Length > 0)
oControl.Visible = true;
}
but the visible property doesnt works with direct events, so my idea was to use javascript instead, can anyone help.
After rendering to the page, visibility cannot be modified since the "visible" property refers to whether or not the client even receives the object to be able to place it on the screen.
I suggest two things if you would like to dynamically change this.
use Hidden="true" rather than Visible = "false" on the page
change your code behind to affect the Hidden property: oControl.Hidden=false;
If you use Hidden property, the client still receives the control to render (it simply doesn't display if set to true), and it can then be quite easily changed.
Please use the Hidden property instead.
The difference is explained here.
Also you can use the Show/Hide methods.
I have a few Input Controls (text) created in the code-behind in this manner as part of dynamic RadiobuttonList (so that a textbox is next to a radiobutton):
RadioButtonList radioOption = new RadioButtonList();
radiobuttonlist.Items.Add(new ListItem(dt.Rows[i][9].ToString() + " <input id=\"" + name + "\" runat=\"server\" type=\"text\" value=\"Enter text\" />")
All the controls are within UpdatePanel.
Everytime there is postback, the text within the Input control disappears.
How do I keep the input text values?
Any ideas? Much appreciated!
The control tree must be rebuilt on every postback, including partial postbacks - or let it rebuild through ControlState/ViewState. In this case, in subsequent postbacks, the Items collection is not rebuilt (or is cleared) and is empty during the Render phase.
For cases like this I would approach it as:
Enable ViewState on the RadioButtonList and ensure it is added no later than Load1, or;
Store the ViewState of an appropriate Collection on the container control and then DataBind the consuming control - see GenericDataSourceControl for a clean way to set this up. I prefer this approach as it's consistent, predictable, and easy to control.
1This ought to work but it might not. I am usually confused as to which controls really support ViewState and to what extent as the usage always strikes me as .. inconsistent. In any case, it won't work if ViewState is disabled - remember that disable ViewState for the page (or parent control) disables ViewState all the way down. Also, the control must be loaded into the Control Tree at the appropriate time and with the same Control Path/ID (usually Init or Load) so that it will correctly function with the request ViewState.
Rough idea for #2:
Save the view state in the containing user control (must have ViewState enabled for this control):
// ListItem is appropriately serializable and works well for
// automatic binding to various list controls.
List<ListItem> Names {
// May return null
get { return (List<ListItem>)ViewState["names"]; }
set { ViewState["names"] = value; }
}
In the GenericDataSourceControl (put the GDS into the Markup so it has a nice ID) Select Event:
void SelectEvent(sender e, GenericSelectArgs args) {
args.SetData(Names);
}
Add the RadioButtonList dynamically (say, in Control.OnLoad):
// Unless this NEEDS to be dynamic, move it into the declarative markup.
// The dynamic control must be added to the *same location* it was before the
// postback or there will be ugly invalid control tree creation exceptions.
var radioList = new RadioButtonList();
someControl.Controls.Add(radioList);
// To minimize problem with Control Tree creation this should be unique and
// consistent for dynamic controls.
radioList.ID = "radioList";
// Binding to the DS "declarative" usually works better I've found
radioList.DataSourceID = "idOfTheGDS";
// You -may- need to DataBind, depending upon a few factors - I will usually call
// DataBind in PreRender, but generally in the Load is OK/preferred.
// If it already binds, don't call it manually.
radioList.DataBind();
If DataBinding is working correctly then it should be possible to disable ViewState for the RadioButtonList .. but sometimes ViewState is used when ControlState should have been, so make sure it functions as desired.
The following code will not add a control to an aspx placeholder:
var control = new ASCXControl { ID="searchFilters", Filters = filters };
var placeholder = Utility.FindControlRecursive(Page, "rightColumnSearchFilters") as PlaceHolder;
if(placeholder != null){
placeholder.Controls.Add(control);
placeholder.Visible = true;
}
When debugging, the placeholder is found and the control shows as added to the placeholder controls collection after entering the block, but yet I see nothing render into the placeholder on the page.
I currently need to pass variables to the control in order to find the filters I need to display. Although I don't like passing variables between controls, I don't see any other way.
What am I missing would make the control not render? Is there a better way to do this?
EDIT:
I am trying to get the HTML inside of the ascx to render. I am able to get the Filters parameters inside the Page_Load on the control.
This may or may not be the whole problem, but usually trying to instantiate a UserControl the way you're doing it leads to problems. You should do it using the LoadControl(path) method of the Page class:
ASCXControl ctl = (ASCXControl) LoadControl("path");
I'm not 100% sure, but I think that if you just instantiate it like an ordinary class/control, you wind up not running all the event handlers (such as Load) that you usually would.
In my case I would like to dynamically add validators to my control based on given logic. For each control I first check something in my DB and if it goes aout that field is required I would like to add requiredField to that control. I firt iterate through each control and if its required I add attribute required="true".
I added this code but it doens work I mean nothing happens, none validation is being made.
if(gc.Attributes["controlid"] != null)
{
RequiredFieldValidator validator = new RequiredFieldValidator();
validator.ControlToValidate = gc.Attributes["controlid"];
validator.ErrorMessage = gc.Attributes["errormessage"];
this.Controls.Add(validator);
}
Thanks for any suggestions.
You also have to add it to the Page's validators collection in order for the server side validation to occur. Adding it just to the page controls collection as you did is what is needed to get the JavaScript validation to get rendered to the browser.
Page.Validators.Add(validator);
Are you adding your Validator control to the same container as the control it validates? Validator controls require the target control to be in the same INamingContainer.
When the Page_Load event gets called to load the page, how would I have the page load already scrolled to a particular id. I cannot use a named anchor # because it breaks my css.
I can use javascript's scrollto function but i don't know how to call javascript from the asp.net page_load event.
I have several headers, and a menu that sorts the contents within each header. So each header has a sort menu. When I sort say Header 2 by "Oldest" I reload the page and change the orderby stuff in my sql and repopulate the repeater under each header. On load I would like the page to load already scrolled to Header 2. I would normally just use #Header2 on the redirect, but I can't use the this anchor method because it breaks my code.
Is there any neat method to accomplish this?
The css issue has to do with full length columns and having a border in the gutter. I know I can use images, but the nature of my pages would require the css to be dynamic to account for the different widths and apply the appropriate background image.
I ended up setting the <body> tag to runat="server" and assigning an id="body". I then added this code in the Page_Load event:
if (Request.QueryString["view"] != null && Request.QueryString["view"] != "")
{
body.Attributes["onload"] = "scroll('" + Request.QueryString["view"] + "');";
}
else //Probably redundant, but I have partial postbacks
{
body.Attributes.Remove("onload");
}
It calls this JS function:
function scroll(id)
{
var a = document.getElementById(id);
if (a != null) {
window.scrollTo(0, a.offsetTop);
}
}
So instead of using #header2, I use a querystring of view=header2 because I have to do a postback anyway. If I just want to go to a named anchor I use onclick="scroll('header2')" in the link.