What's the proper way to implement FindControl - asp.net

Sorry in advance for the long question.
Since I'm running into StackOverflow exceptions (ironically), which i know the cause of, i am really wondering whether i've got my concept, of how to implement FindControl right.
My idea was, that if you're implementing a custom child control collection, which should be accessible to FindControl, you'd have to implement FindControl and search through your list in addition to calling the base method.
So this is the situation now:
I wrote a Server Control, which has a templateproperty (which i'm adding on init). Let's call that "panel" for now (It's not the default asp one)
My structure is along the lines of this:
panel (1)
panel (2)
telerik:RadTabStrip
panel (3)
telerik:RadMultiPage
Now prior to my change finding controls worked ok, with the exception that if the radTabStrip would look for the multipage through its id it would start looking in 2, where it obviously can't find the other multipage, since it's not a direct child of 2.
My change was to go to the NamingContainer (leads to 3) and loop through the child controls and execute FindControl there. This initially worked to solve this issue.
However in a structure where there was 3 children and the desired control was the third this way of searching would result in dancing back and forth between the first and the second panel. So it's a sibling search which triggered the StackOverflowException, which makes sense.
Apparently however this raised the question for me if i'm not actually doing something terribly wrong there. Other controls seem to have no trouble looking through hierarchies of NamingContainers without any hassle.
Is there some ID name register (e.g. all controls within naming container register their contained id's and in findcontrol you'd just go to some look up class to find the control you want without any custom logic to navigate through controls and calling FindControl) I'm not aware of, or something alike?
I really hope you can help me with this one.
I have an idea how to solve my issue for this problem, but I'd love to know how to actually do this the way it's supposed to be done correctly.

Each Control has its own Controls collection, that is 'built in' - you do not need a 'naming register'.
You basically need a recursive function:
Write, for example, MyFindControl so that it accepts a Control-Collection as a parameter.
Have your function iterate through that collection, and if you find the control (by name?) you're looking for, return it.
And if the control you're currently checking is not the one you're looking for, let your function call itself again, giving that control's control collection as a parameter.
If the control that is being searched does not turn up, you can return Nothing or Null (depending on your language), or you can raise an error. The code using your custom FindControl implementation must handle that.

Related

ASP.NET how to pass a reference to a particular control

I'm generally an ASP.NET MVC guy, so the "standard" ASP.NET stuff is a little difficult for me to wrap my brain around. I've tried looking for the answer, but the keywords I'm using seem to be too generic... I get a lot of close answers, but not what I'm actually looking for.
I have a grid that is populated from a data set. One of the fields is a dropdown with 4 possible statuses. When the user selects a status, an event is fired in the codebehind to make the change in the db immediately.
There is a particular status that I need to confirm, because once it's selected, it's irreversible. Figuring out how to have the back end pop up a confirmation box was annoying, but I think I have that part done now.
The problem is, if the user confirms that the status they selected for the dropdown was intended, I need to disable any further changes to that dropdown, either by disabling the control or by removing the row altogether. With this requirement, I imagine I need to pass a reference to the specific control that fired the event back to the script, so that it can pass it through the postback, where I would need to consume it.
I have no idea how to pass a reference to the control (what can be used as a reference?) and I have no idea how to use that reference in the postback.
Any help would be greatly appreciated.
;p i was waiting for you to find my post on the issue lol.
but to put it simply, you postback to the page, all members are still available to you if you instantiated something in codebehind. if not, then use FindControl to pull them from DOM. here's the passing values stuff.
as long as you don't kill the lifecycle, you're fine: Passing dropdownlist selected value to another page's dropdown list
and here is the linkspam (full docs): How do I keep TCP/IP socket open in IIS?
probably the articles on session-state and page lifecycle will be of most use.
To prompt the user for confirm add this attribute to dropdownlist.
onchange="return confirm('Confirmation Message');"

What is the most efficient way of changing content before render (ASP.Net)

We are using a CMS and I need to alter correct some of the HTML that is being generated by a control that is completely black-boxed. Usually I would sub-class the offending control and tweak it within that, but because of the way the control has been written I am unable to remove the offending attribute.
This leaves me the only option of performing this operation through the Render method on the master page itself. I was thinking of changing the content string before it is rendered, this would involve a bit of Regex in a bid to remove the invalid attribute being rendered.
Given that this operation will run on every page, is this the most efficient way of achieving it? Should I perhaps do a string.Contains() to check for the existance of the HTML element first? Is using Regex for this going to cause performance issues?
First, does this have to run on every page? If so, that is fine, but if you are merely running on every page because it is the solution you have currently in your mind, then it might be better to go back to the business problem at hand.
If you want an architectural decision, "fix before binding" is preferable to "fix in a rendering method". This is regardless of master page or not. I would rather massage a "data set" to using row binding events, as the code shows clearer intent and usually performs better.
I would also consider caching if this is the same content over and over again. If it is not, then why are you using the master page. And "it has a render event" is not a good reason.
Hope this helps.

ASP.NET dynamic controls data exchange in postback

Please excuse me for a probably low quality of this question, since I'm not a web dev, so I possibly don't now some obvious things and don't know what to Google for. I think problem must have some simple solution, but I'm struggling with it for two days now, so I feel myself pretty stupid :-).
I have a custom control which is a set of checkboxes which are added dynamically based on a property which is set in OnLoad event of a page. I have two such controls on a page and second control items should be based on items selected in first control.
The problem is, I can't figure out, how to catch on autopostback which boxes were selected in first control before second contol is constructed to pass this data to it?
Take a look at this.
http://forums.asp.net/t/1440174.aspx
Since your building them dynamically, they are not as easy to find as webforms would like to be, if you added them to the page and wired up events and such.
Your going to look at the Request.Forms list, and search thru it for any controls you want.
I believe checkboxes are like radio buttons, they only return if they are checked, which is good, cause you want to know which ones were checked.
I've used same solution as in the accepted answer for this question: Dynamically Change User Control in ASP.Net , just need to assign an unique id for each dynamically created CheckBox in custom control. Not as clean solution as I want but at least it works.
You can save the data in the ViewState, QueryString or as Session before moving to the next page and you can do modifications based on it.

Custom SelectedValue attribute

I am creating a completely custom (only inherits from WebControl) combobox/dropdownlist search control with autoComplete capabilities.
JQuery handles assigning the onhover and onclick events for list items (divs with strings in them) and handles the web service call for getting the list of items for the matching text.
The server handles the custom attributes and control rendering.
The issue is that I need to implement a property that is similar to SelectedValue so that when a user selects an item from the search results, the value can be used on the server for other processing. I have done days of research but have not found a clear, concise way of handling the post back data.
I did read a blog that mentioned implementing the IPostBackDataHandler interface, but the implementation of RaisePostDataChangeEvent() calls for calling a server method (like SelectedIndexChange) that I am not implementing at the moment.
public void RaisePostDataChangedEvent()
{
this.SelectedIndexChanged(EventArgs.Empty);
}
Now for the question: Does anyone have advice for handling this? Or am I better off simply inheriting from the dropdownlist control and overriding the existing functionality?
I feel like I'm missing a very small piece that will fit this all together.
Have you considered pulling down the source code from Microsoft's source server and taking a look at how they implemented DropDownList? This would allow you so see how they solved the binding and events part of the problem and give you a good idea what it does otherwise. This way you can decide if you want to inherit from it, or if you can just borrow some ideas for how they implemented IPostBackDataHandler.
Since I have no idea what specifically you are doing, I couldn't advise you if you should inherit from dropdown as it is, but based on my impressions of what you are doing I'd say you probably don't.
Also you might look at source from the AjaxControlToolkit as it has a similar component. Again, you can get ideas for how these specific things are handled and adapt them to your own needs.

ASP.NET: How to initialize when *user control* is initially loaded

I have an ASP.NET user control that I'm embedding in another user control. This works fine.
I need to know the best logic/method for detecting when the control is loaded. In other words, I have some display initialization logic that needs to run when the control is initially displayed. Surely there is a pattern for this.
The typical method is to put (!IsPostBack) logic in the Page_Load method of the control. This works great until you end up with a state when the Parent page has already posted back many times. My user control gets added to the page but its display does not intialize properly.
I'm hoping to find a way that keeps this logic inside the control, versus various hacking around in the codebehind of the parent page.
See the following MS article. They have an example that places several controls within a user control and initializes them.
There is another post here on StackOverflow that seems similar. You may want to check it out, and see if it points you in the right direction.
It may also be helpful to review the page life-cycle and events.

Resources