Custom SelectedValue attribute - asp.net

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.

Related

What's the proper way to implement FindControl

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.

asp.net usercontrol development/implementation

I've developed an ASP.NET user control, instances of which may appear several times on a single page. Without getting into too much application detail, when the value of any one of the instances changes, all of the other instances need to be refreshed. Currently, in order to accomplish this, I'm requiring that the consuming page implement a couple of methods which iterate through each control on the form, find all the instances of my user control, and call a Refresh method in each one.
Functionally, it's working perfectly. However, I'd like to force the developer of the consuming page to implement these two methods exactly as per my requirements. I could have them implement an interface, but that doesn't provide the functionality in each method. Or I could have them extend an abstract class, but in either case (interface or abstract class) how can I force them to inherit? I need something that will trigger a compiler error if the necessary abstract class is not extended by the consuming page. Any ideas?
Thanks.
You can enforce implementation by using 'abstract methods' in C# or using the 'MustInherit' keyword in VB.NET.
In your particular case, you're expecting the developer to essentially implement 'your' code to force the refreshing and this is something I wouldn't want delegate. Without knowing too many details I would be tempted to utilise the 'Observer' design pattern or possibly the 'Mediator' using either a separate object as a controller or even applying the controlling / publishing code to the webpage. Here's a practical example of the 'Observer' in ASP.NET.
HTH

ASP.NET 4.0: Is it possible to make some user control's child controls public without using FindControl or public properties?

I have a custom user control that contains text boxes, dropdowns, etc. I need these controls to be public so that I can go like ucEmployeeAddress.txtAddr1.Text from outside the control.
I know that I can use public properties in the control that return an instance of the control inside or use FindControl to locate my control from outside the user control, but I don't want to do that due to excess code.
If there is no way to do what I want then I will just go the public property route.
Edit: Would the person who thumbed my question down be so kind as to explain how my question shows lack of research effort, is unclear, or not useful?
You just need to expose a property in the user control:
public string Address
{
get
{
return txtAddr1.Text;
}
set
{
txtAddr1.Text = value;
}
}
Do you really need to expose the entire control ?
If its just the text property you could just expose that.
public string TitleText
{
get { return this.txtTitle.Text;}
}
If you really need the control i would suggest exposing it via a property, consumers may not even know the existance or name of the control, and nor should they care about your internal workings - using FindControl is a poor solution from outside of the control.
public TextBox TitleTextBox
{
get { return this.txtTitle;}
}
As an alternative you may be able to modify the visual studio templates to expose all your controls as public, however im not sure if this is such a great idea or how you would do it..
Well, about three hours later, I finally came upon a solution. I don't know if this is new in VS2010, but you can actually edit the user control's designer and turn all members from Protected to Public. I swear I've tried this with earlier versions of VS in the past without success, but it's apparently working for me now.
What's interesting is that the IDE has a keen sense of what parts of the designer it should and should not regenerate. For example, if you comment out the entire contents of the designer class, it will not regenerate the commented-out members. To get it to regenerate them, you have to completely delete the members that you want regenerated. What's also cool is that you can comment out the entire designer class's contents, switch back to the markup and add a server control like a textbox, and flip back to the designer to discover that it generated the member definition for only that control while the rest of the member references remain commented-out. Edit: And if you delete a control from the markup whose designer member you had modified from protected to public, it will still delete the reference from the designer.
I will note that I am also using VB.NET. I would have to assume this works with C#, as well, but cannot say for sure.
The proper way to do this is through event bubbling. This way you can keep the implementation of your controls hidden while being able to modify the properties that you chose.
This link does a good job explaining how to accomplish this.
As a side note, you should be more concerned with the elegance of your code than the amount of it.
If you take the time to implement event bubbling, for example, as opposed to exposing the control's children as public, any manipulation of the control's children is handled by that control. This makes it easy to maintain if ever the logic of manipulation were to change, and easy to implement across your entire application.
However, if you expose your control's children as public instead, you must repeat that manipulation everywhere it is used.
Therefore, the "excess code" will both improve the quality of your code and actually decrease this "excess code" you are concerned about.

How do you handle attaching JavaScript to UserControls in ASP.NET and keep multiple instance isolated?

Lets say you need to attach some JavaScript functionality to an ASP.NET User Control of which there might be multiple instances on any given page. Because JavaScript has shared global state, what techniques can you use to keep the client state and behavior for each instance of a control separate?
Well, the main thing you can do is make sure your JavaScript functions are abstract enough that they are not coupled to specific instances of HTML controls - have them accept parameters that allow you to pass various instances of objects in.
The JavaScript that does whatever magic you need to be done should only exist once in your page regardless of how many instances of a user control you have on a given page, thus your functions need to be ignorant of that fact.
Without more information about what you are trying to do, there is little more I can offer in the way of help; it would depend on your circumstance.
EDIT: One way I have dealt with particular aspects of this problem is to create a static property on the user control (thus it is the same variable across multiple instances) that tracks the client-side IDs of the various user control elements (the user control adds the client IDs to this list in the control's OnLoad event); then, in the page's OnPreRender event (IIRC), render those out in a JavaScript variable that my code knows to look for on the client and operate on. I don't know if that makes sense, but it might help someone...
function <%=this.ClientID %>_myButton_onclick()
{
DoSomething();
}
and
<button id="myButton" onclick="<%=this.ClientID %>_myButton_onclick()">
Notice in this case the control is a regular HTML control.
If your control has more than one function, you can put it in an external js files and refer to it.
this.Page.ClientScript.RegisterClientScriptInclude("searchcontrol.js","includes/searchcontrol.js");

ASP.NET Custom Controls and "Dynamic" Event Model

OK, I am not sure if the title it completely accurate, open to suggestions!
I am in the process of creating an ASP.NET custom control, this is something that is still relatively new to me, so please bear with me.
I am thinking about the event model. Since we are not using Web Controls there are no events being fired from buttons, rather I am manually calling __doPostBack with the appropriate arguments. However this can obviously mean that there are a lot of postbacks occuring when say, selecting options (which render differently when selected).
In time, I will need to make this more Ajax-y and responsive, so I will need to change the event binding to call local Javascript.
So, I was thinking I should be able to toggle the "mode" of the control, it can either use postback and handlle itself, or you can specify the Javascript function names to call instead of the doPostBack.
What are your thoughts on this?
Am I approaching the raising of the events from the control in the wrong way? (totally open to suggestions here!)
How would you approach a similar problem?
Edit - To Clarify
I am creating a custom rendered control (i.e. inherits from WebControl).
We are not using existnig Web Controls since we want complete control over the rendered output.
AFAIK the only way to get a server side event to occur from a custom rendered control is to call doPostBack from the rendered elements (please correct if wrong!).
ASP.NET MVC is not an option.
Very odd. You're using ASP.NET server controls and custom controls, but you're not using web controls? And you're calling __doPostBack manually?
Do you like to do things the hard way?
If I was still using the server control model rather than MVC, I would slap ASP.NET Ajax controls on that sucker and call it a day. What you're doing is like putting a blower on a model T. It may be fun and interesting, but after you're done with all the hard work, what do you really have?
I have been doing some more digging on this, and came across how to inject Javascript in to the client when required. This will obviously play a huge part in making the controls more responsive and less round-trips to the server.
For example: RegisterClientScriptBlock.
Look forward to playing with this more, feel free to get invovled people!

Resources