Easy one here.
I have a control inside a control inside a masterpage. The page name looks something like this in HTML
ctl00$MasterPageBody$MainControl$ChildControl
Any idea how I can get the above from code behind?
Thanks!
It's the clientID property of the control.
If we're talking about a top-level control on the page, or at least one that isn't in any sort of repeating type, you can just use the ClientID property.
<asp:Label runat="server" ID="testLabel" />
<script>
$('#<%= testLabel.ClientID %>').click(function() { ... });
</script>
If we're talking about something that isn't accessible directly like that, you'll have to do the same thing, but it'll have to be wrapped in a FindControl. The example of that isn't so clean, so I'll trust you can understand from my words. But basically, if you have a label that shows code-behind-given text on each row of a GridView, you'll have to call ((Label)e.Row.FindControl("testLabel")).ClientID. Still pretty straight-forward, but a bit more complicated than the first case.
You should use a function similar to this:
public static Control FindControlRecursive(Control ctl, string id) {
if (!ctl.HasControls())
return null;
Control res = null;
foreach(Control c in ctl.Controls) {
if (c.ID == id) {
res = c;
break;
} else {
res = FindControlRecursive(c, id);
if (res != null)
break;
}
}
return res;
}
in this way:
Control ChildControl = FindControlRecursive(this.Page, "ChildControl");
string ID = ChildControl.ClientID;
Related
I have a user control which is in common in two asp.net pages how to find out the parent page i dont want to use the page's title is there any concrete way to determine may be a page's class or any way else
I would like to do this
if (this.page == "pagename")
{
//do this
}
else
{
//do this
}
You can use this.Page in order to find the current page and use this.Page.GetType() if you are expecting class name
You can use:
Page myParentPage = this.Page;
In your method.
Try this:
if (this.Page.GetType().Name.ToLower() == "pagename".Replace(".", "_").ToLower())
{
//do this
}
else
{
//do this
}
Is there a way to access a group of controls in ASP.NET somehow?
In jQuery you can access multiple elements using a class="somegroup" like
$('.somegroup')...
In ASP.NET I understand I can access an element or control using the ID, but is there a way to access multiple controls or elements at once?
For example, let's say I have this in design view:
<asp:Label ID="label1" CssClass="someclass"></asp:Label>
<asp:Label ID="lbl" CssClass="someclass"></asp:Label>
<asp:Label ID="lb2" CssClass="someclass"></asp:Label>
Now I want to turn the visibility off on all of them.
Instead of doing this:
label1.Visible = false;
lbl.Visible = false;
lb2.Visible = false;
Is there an equivalent to this?
someclass.Visible = false;
Is there possibly a different tag property I could be using?
using asp.net and C#
You may write your own function, pass a string class into it (and optionally a parent control or form) then loop thru Controls collection checking for the CssClass property and making needed modifications for matched controls.
Something like
void hide(Control el, string cssClass) {
foreach (WebControl c in el.Controls)
{
if (c.CssClass == cssClass)
{
c.Visible = false;
}
}
}
and call
hide(this, "someclass");
public void Apply(string selector, Control parent, Action<WebControl> a)
{
if (selector.StartsWith("."))
{
foreach(WebControl wc in parent.Controls)
{
if (wc.CssClass == selector.Substring(1))
{
a(wc);
if (wc.HasControls())
{
Apply(selector,wc,a);
}
}
}
}
if (selector.StartsWith("#"))
{
foreach (WebControl wc in parent.Controls)
{
if (wc.ID == selector.Substring(1))
{
a(wc);
return;//no need to search any further.
}else
{
if (wc.HasControls())
{
Apply(selector, wc, a);
}
}
}
}
}
Maybe this will help?
then you can do this:
Apply(".SomeClass", this, a => a.CssClass="SomethingElse");
There is no baked-in syntax for doing a selector-type operation in C#.
You can however write your own loop to do this, like this:
private void SetAllLabelsWithCssClassValueToInvisible(Control parentControl,
string className)
{
foreach(Control childControl in parentControls.Controls)
{
// Try to cast control to a label, null if it fails
var label = childControl as Label;
// Check to see if we successfully cast to label or not
if(label != null)
{
// Yes, it is a label
// Does it have the correct CssClass property value?
if(label.CssClass == className)
{
// Update the Visible property to false
label.Visible = false;
}
}
}
}
Note: Obviously you can expand/improve upon this notion and make it fit your needs, just a proof of concept that is very specific for Label controls with a particular CssClass value and the Visible property.
Internally, the jQuery Sizzle engine is doing this looping for you.
There is a problem to find a dynamic control on a page. The dynamic control is created every time when a user press a button. The button calls the following JavaScript function and create a new components.
<script type="text/javascript">
var uploadCount = 1;
function addFileInput(fName) {
var only_file_name = fName.replace(/^.*[\\\/]/, '');
var $div = $('<div />', {runat: 'server'});
var $cbox = $('<input />', { type: 'checkbox', id: 'attachement' + uploadCount, value: fName, checked: "true", runat: 'server'}).addClass;
var $label = $('<label />', { 'for': 'attachement' + uploadCount, text: only_file_name });
$div.append($cbox);
$div.append($label);
$('#newAttachment').append($div);
$("#uploadCountValue").prop("value", uploadCount);
uploadCount++;
}
</script>
newAttachment is DIV section on the page.
<div id="newAttachement" runat="server" />
The DIV section is situated inside section. The problem is when a user presses the button on the form I can't find the dynamic created components. The following code shows how I try to find the components:
for (int i = 1; i <= Convert.ToInt32(uploadCountValue.Value); i++)
{
if (RecursiveFind(newAttachement, "attachement" + i) != null)
{
... to do something
}
}
public Control RecursiveFind(Control ParentCntl, string NameToSearch)
{
if (ParentCntl.ID == NameToSearch)
return ParentCntl;
foreach (Control ChildCntl in ParentCntl.Controls)
{
Control ResultCntl = RecursiveFind(ChildCntl, NameToSearch);
if (ResultCntl != null)
return ResultCntl;
}
return null;
}
I have detected that Controls count value is always zero in spite of there are dynamic components there.
I would be happy to get any help from us. Thanks.
to find the controls created in the client-end you can't search them in the Page.Controls collection instead try to look for them in the Request.Form[] array
you are creating the dynamic controls in javascript? i.e. you are creating html elements in javascript. It won't matter even if you put a runat="server" attribute in there, because it is still at the client-end. That would not be a part of the viewstate bag, so not populated in the controls collection.
you need to change your logic. create dynamic control in code-behind on button postback.
I have a search textbox situated on a masterpage like so:
<asp:TextBox ID="frmSearch" runat="server" CssClass="searchbox"></asp:TextBox>
<asp:LinkButton ID="searchGo" PostBackUrl="search.aspx" runat="server">GO</asp:LinkButton>
The code behind for the search page has the following to pick up the textbox value (snippet):
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
Page previousPage = PreviousPage;
TextBox tbSearch = (TextBox)PreviousPage.Master.FindControl("frmSearch");
searchValue.Text = tbSearch.Text;
//more code here...
}
All works great. BUT not if you enter a value whilst actually on search.aspx, which obviously isn't a previous page. How can I get round this dead end I've put myself in?
If you use the #MasterType in the page directive, then you will have a strongly-typed master page, meaning you can access exposed properties, controls, et cetera, without the need the do lookups:
<%# MasterType VirtualPath="MasterSourceType.master" %>
searchValue.Text = PreviousPage.Master.frmSearch.Text;
EDIT: In order to help stretch your imagination a little, consider an extremely simple property exposed by the master page:
public string SearchQuery
{
get { return frmSearch.Text; }
set { frmSearch.Text = value; }
}
Then, through no stroke of ingenuity whatsoever, it can be seen that we can access it like so:
searchValue.Text = PreviousPage.Master.SearchQuery;
Or,
PreviousPage.Master.SearchQuery = "a query";
Here is a solution (but I guess its old now):
{
if (PreviousPage == null)
{
TextBox tbSearch = (TextBox)Master.FindControl("txtSearch");
searchValue.Value = tbSearch.Text;
}
else
{
TextBox tbSearch = (TextBox)PreviousPage.Master.FindControl("txtSearch");
searchValue.Value = tbSearch.Text;
}
}
I've got a web page where I am dynamically creating controls during Page_Load event (this is done so because I do not know how many controls I will need until session is active and certain variables are accessible)
I need to be able to loop through these controls to find Checkbox when a button click is processed. Looping through the Form.Controls does not appear to be sufficient. I would think that Request.Form might work but it does not appear to be accessible in my C# block?
What should code for Request.Form look like? OR
Has anyone done this before with dynamically created controls?
Any insight is appreciated.
Simplified Example from MSDN:
var myControl = FindControl("NameOfControl");
if(myControl != null)
{
//do something
}
else
{
//control not found
}
Hope this helps! ;)
Your controls will be accessible trough the Controls collection of their immediate parent. Unless you add them like Page.Form.Controls.Add (myControl);, you won't find it in Page.Form.Conttrols. If you add them to a place holder, you must find them in thePlaceHolder.Controls.
LinkButton myDynamicLinkButton = new myDynamicLinkButton ();
myDynamicLinkButton.ID = "lnkButton";
myPlaceHolder.Controls.Add (myDynamicLinkButton);
//........
LinkButton otherReferenceToMyLinkButton = myPlaceHolder.FindControl ("lnkButton");
As #David said in his comment, you should probably think about using a Repeater instead. It would probably simplify your case a lot.
Since the controls might be nested in other controls, you need to search recursively. You can use this method to find the control:
public Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
And you can implement it this way:
CheckBox check = FindControlRecursive(Page.Form, "CheckBox1");
You should have access to Request["xyz"] anywhere in your aspx.cs code. You can either find control as described above and read it's value or do so directly from Request using the Control.UniqueID property. For example if it's a checkbox that's within the repeater then the UniqueID would look like dtgData$ctl02$txtAmount
Thanks for the insight guys. I kind of took the discussion and ran with it and found my solution that worked best for me.
foreach(String chk in Request.Form)
{
if (chk.Contains("chkRemove"))
{
int idxFormat = chk.LastIndexOf("chkRemove");
objectname = chk.Substring(idxFormat);
}
}
Turned out really all I needed was the name. The string contained a number at the end which was needed to determine a position of datatable items. Thanks for the advice!