Get an ascx on a aspx - c#

I have a UserControl that consists of a Parent and Child UserControls that is displayed on a aspx page. I need to get the instance of the Parent UserControls from the child controls. The Parent has a set of nested .net controls and in these nested controls the child UserControls are displayed so if I use this from a child UserControls
MyControl _myControl = (MyControl)this.Parent.Parent.Parent.Parent.FindControl("MyControl");
where (this) = the child control and (Parent.Parent.Parent.Parent) walks me back the tree to the real parent.
This will get me there but there just seems to be a better way. Any suggestions?

An ascx shouldn't know anything about its parent(s): that's a sign that it's too closely coupled to other classes. They might as well be one class.
One alternative is to follow the law of Demeter: figure out what this (your user control) needs from MyControl, make it a property, and let your aspx provide it rather than asking for it.

If you're using a master page, you can start from there and use the container id to find the control. It just depends what the control is closer to.
This might help:
http://www.asp.net/master-pages/tutorials/control-id-naming-in-content-pages-cs
Another thing you can do if you're accessing a value from a control in a parent page, is to put that value into the HttpContext.Current.Items["MyControlValue"] on page load. That way your usercontrol can grab that value easily

Related

How to identify the topmost parent control?

I am automating a WPF application using Coded UI.
So, while creating a object of a control say WpfText i need to say:
WpfText tag = new WpfText(parent);
Here i need to pass the parent control to the constructor, So is there a way to find the parent control of a particular control in wpf application?
I can record it using Coded UI test builder and then see the generated code but is that the only way ? bcz i find it too cumbersome to do this way.
Within a Coded UI test the TopParent property of the UITestControl class, see here for more details, can be used. To move up through the ancestors of a control towards the top parent the GetParent method of the same class, see here, can be used. There are several other methods in the class for other ways navigating through the control hierarchy.

Move UserControl to another parent in Page Stack

I have a page of controls that I want to be able to move specific controls by ID to a different parent control server side.
A simple example being another control loads 2 controls vertically ontop of each other. I want a module that can reference those two modules by ID and lay them out horizontally.
I assume this would have to done after the Page_Load() event so that all the controls are loaded.
I think I can accomplish this with a recursive control.FindControl() but I'm thinking there is a more elegant way.
If you plan to dynamically move controls around the page then it’s better to programmatically set them on page where it’s needed.
You should be adding controls in the OnInit method that is run before the page load.
Roughly, the OnInit method would look like
a) check the state of the page and decide where to add control
b) add control where needed

Reordering the position of usercontrols on a ASP.NET page

I am working on a page that has user controls that are arranged in a particular layout. I am modifying that page to support reordering the position based on user's preferences. So, essentially, on load, I have information on where I need to position the different user controls.
I can think of 2 approaches:
Do the reordering on the client side. This is not ideal for the user
as they see the reordering happening.
Do the reordering on the server side. This requires me to do a lot of
rewrite to dynamically load the user controls based on preferences.
Are there any other ways of accomplishing what I am trying to do?
I would recommend rearranging on the client-side because
You will save a post-back.
You will make the website seamless.
How can do you that
Use a main div containing all controls and another containing a loading image. Toggle there visibility while rearranging the controls using javascript, or
You can set visibility:hidden to your body and then after rearranging set visibility:visible
The drawback of this approach is that you will have to use absolute positioning.
There is an easier way; rendering is controlled by the parent container rendering them. It is possible to create a container, and have full control over the ordering of the rendering of its children (by overriding the RenderChildren method). It's not the easiest option, but it can work. The steps are:
Create a class that inherits from ContainerControl
Override the RenderChildren method
Within this method, it would render the children in the container, override it, do not call the base class version of it, and get the instances to the controls and render them. This is where the complication arises because you have to.

PostBackTrigger for nested control

I have an UpdatePanel which contains all my page (I know, not an ideal solution), and I have some Panel's contained in this. Inside one is a control which I want to be a PostBackTrigger, but whenever I reference the button I get object reference errors, presumably because the control is nested. How can I expose this for the UpdatePanel?

How do I add events to nested server controls? (ASP.Net)

I am building a custom master page type control i.e. sort of like a datagrid but should be easier to add custom functionality into it. It's going great but part of the desired functionality is to have a paging control that switches on and off and part of that control would be a textbox that displays the current page number and on TextChanged redirects to the new page of the dataset.
The problem I'm having is that technically the textbox which has its event fired is embedded in a control that is embedded in the control you actually put on the page sort of like
Page
|
Display Control
|
Paging Control
|
Textbox
Buried all the way down there the event is not firing. Worse the postback javascript isn't even being written onto the page (Nothing on the page posts back so far this is the only bit that really needs to).
I've been trawling around Google for quite a while now and picked up that I need to implement INamingContainer (done) and I need to add the control into the page's control tree (is Pre_Init too late for that? When's a good time to Add the Control to the page?) then the event should fire, apparently. But I've been unable to find an example of best practice on this there are quite a few near misses where people are having button angst but this isn't a button.
So can anyone point me in the direction of getting a control embedded in a control embedded in a control added to a page to behave properly?
You need INamingContainer only if you plan to add more than one instance of your custom control to the same page. What it does is enabling unique id generation so you don't end up with controls with the same ID. I recommend you inherit from CompositeControl when creating your custom control.
Pre_Init is not too late. Actually it is pretty early considering the lifecycle. You can instantiate custom controls and add them to the live controls collection in a lot of places. I would recommend you do it in Page_Init (before viewstate is loaded) or Page_Load(after view state is loaded). Even if you add it later in the page lifecycle the control will catch up in events.
To subscribe to events of child controls you can use the FindControl method:
MyControl myControl = Page.FindControl("MyControl1");
TextBox textBox = myControl.FindControl("TextBox1") as TextBox;
The answer was a combination of the above answer and the comment on the original question. The vital thing to get the event to happen is to make sure that your controls (parent and child) inherit from CompositeControl and INamingContainer e.g.
public partial myControl:CompositeControl,INamingContainer
etc...
Then you override your composite control's CreateChildControls() method and create your controls and do the wire up there. This will ensure correct bubbling. and mean that the event handling takes place within your comoposite control...

Categories