Find control on aspx from ascx

Go To StackoverFlow.com

4

I'm trying to find a label on an aspx page from a user control (ascx) on said aspx page. Obviously Page.FindControl("lablel1") is not working. Do I need to add in ClientID somewhere? Thanks.

2009-06-16 19:22
by halp
I assume that the typo in your question (you use "lablel1") isn't the source of your problem - Dan Davies Brackett 2009-06-16 19:35
you assume correc - halp 2009-06-16 19:37


14

I think you ought to stop and think about your design. Your controls should not ever need to know anything about the page that contains them - the fact that you need to go find a control on the page from within another control tells me that you ought to rethink the problem.

The best thing I can tell you (with what little I know of your architecture) is that you ought to pass in a reference to the control you hope to find into your user control. This way your control does not have to know about things outside itself.

2009-06-16 19:26
by Andrew Hare
Maybe, but that isn't the question. In this instance, there is a page which has an "Error/Status Label" whose value is set by any user control on the page. It used to be accessed statically by index, now I'm trying to change it to use some kind of FindControl - halp 2009-06-16 19:33
+1, passing in a reference to the error label is a better way to go here - Dan Davies Brackett 2009-06-16 19:36


3

When using FindControl() outside of the context of the control's immediate parent, you will need to walk the control tree to find which level your label lives in and call .FindControl() at the appropriate level.

That said, take @Andrew Hare's advice and revisit your architectural decisions. There is likely a better way to have your UserControl interact with its consuming page.

For example, you can expose a public event in your UserControl and add an eventhandler to your consuming page (or base page/masterpage). When creating an event you can make the signature what ever your want, so go ahead and include the error text which needs to get passed.

If you want to get funky with it, you can turn your Error label into a custom control with hooks into the event.

Sample Event:

Public Event UserErrorOccured(ByVal ErrorText as String)

Sample Error:

If Not Page.IsValid Then
    RaiseEvent("The page is not valid")
End If

Sample Handler:

protected sub UserEventHandler(ByVal ErrorText as String) Handles MyUserControl.UserErrorOccured
    errorLabel.Text = ErrorText
End Sub
2009-06-16 19:48
by Rob Allen


3

Something like this should work if the hierarchy is predictable.

Me.Owner.FindControl("controlName")

or...

Me.Owner.Parent.FindControl("controlName")

or...

Me.Owner.Parent.Parent.FindControl("controlName")

If it's not predictable, then you'll have to write a recursive (expensive) function to find the control instead. Be careful with your approach here though, because this type of algorithm can become slow and unwieldy if overused on large pages.

Here's an example in VB for searching through the tree backwards (from child to parent) and finding a control:

Protected Function FindControlByID(ByRef childControl As Control, ByVal ID As String) As Control
    Dim ctrl As Control = childControl.FindControl(ID)
    If Not ctrl Is Nothing Then
      Return ctrl
    Else
      If Not childControl.Parent Is Nothing Then
        Return FindControlByID(childControl.Parent, ID)
      Else
        Return Nothing
      End If
    End If
  End Function

I'd call it like this:

Dim lbl As Label = FindControlByID(Me.Owner, "label1")
2009-06-16 19:52
by Steve Wortham
When is the hierarchy predictable for more than one or 2 updates to the source code - Rob Allen 2009-06-16 20:09
Well, from what I've seen in the past, the hierarchy changes when you move a control in or out of a container (placeholder, panel, user control, etc). As long as you don't do that, then it is fairly predictable.

Of course, on the other hand, this is one of those crappy solutions that when something does change, it'll break and you may not remember why. But that's just a reason to avoid doing this to begin with, if you can - Steve Wortham 2009-06-16 20:19

I added a function that'll search for the control through the entire tree - Steve Wortham 2009-06-16 20:25


2

Create an interface, such as:

public interface IStatusDisplayer
{
   Label StatusLabel { get; }
}

Implement the interface on any page that displays the error/status label. If your user control needs to access the label you can do this:

var statusDisplayer = this.Page as IStatusDisplayer;
if (statusDisplayer != null)
{
    statusDisplayer.StatusLabel.Text = "Hello World!";
}
2009-06-16 20:05
by Jamie Ide


1

From within the user control

Me.NamingContainer.FindControl("label1")
2009-06-16 19:58
by Achilles


1

Control ct = WebUserControl11.FindControl("DropDownList1");

DropDownList dt = (DropDownList)ct;

TextBox1.Text = dt.SelectedValue.ToString();
2012-06-25 11:15
by HAris


0

A couple of other ideas come to mind. There is the "Items" collection in the Page class that could be used to store a value or the Session object for a similar thought. Another is to expose a public method on the page to update the label. There may be AJAX issues with that architecture as I'm not sure how well the callback can update multiple areas of a page at the same time, so this is just a warning and I'm not saying I have had this problem.

TheSteve's answer also works and is how I've done it when I had to in the past though it can be tricky tossing around controls. I would also second Andrew's answer though.

2009-06-16 20:03
by JB King


0

This is simple, first you need to access the master page ContentPlaceHolder:

Dim ContentPlaceHolder1 As ContentPlaceHolder = TryCast(Page.Master.FindControl("ContentPlaceHolder1"), ContentPlaceHolder)

Then using the ContentPlaceHolder you can now find the ID of the control on the aspx page:

TryCast(ContentPlaceHolder1.FindControl("LiteralOnParentASPXPage"), Literal).Text = "some text" 
2013-05-09 14:33
by michael


0

This is a brute force method, but it works when the control is buried deeply in the hierarch of controls:

private Control GetTextEditor(ControlCollection controls)
{
    foreach (Control ctrl in controls)
    {
        if (ctrl.ID != null && ctrl.ID == "teMessage")
            return ctrl;
        if (ctrl.Controls.Count > 0)
        {
            Control inner = GetTextEditor(ctrl.Controls);
            if (inner != null)
                return inner;
        }
    }
    return null;
}
2013-07-11 17:09
by Karin


0

To access means enable/disable controls from .ascx in .aspx file, Try this code it is also the solution.

protected void Page_Load(object sender, EventArgs e)
{
    Control ct = PEM.FindControl("btnInsert");
    Button btn = (Button)ct;
    btn.Enabled = false;
}
2016-11-28 10:40
by Ehsanullah Lodin
Ads