I have a UserControl that provides some functionality (loads and displays a client's information) and I want to extend that UserControl. Some forms require the plain old UserControl while other forms will require some additional fields. How can I inherit from the existing UserControl, maintain the existing fields but add new fields on as well?
I like the way MasterPages work, where you define place holders, and then the content pages just fill those places holders with extra content. Is this possible with UserControls? Thanks!
Perhaps you could define a few ASP:PlaceHolders (think of it as "zones") within your UserControl and make them available via public (or protected if you only want the inherited class to be able to change them) properties. That way you can add subcontrols to them whenever you need to.
protected PlaceHolder TopZone {
get { return plhTop; }
}
protected PlaceHolder BottomZone {
get { return plhBottom; }
}
From one of the inherited UserControls:
Label lblTest = new Label { Text = "Hello World!" };
TopZone.Controls.Add(lblTest);
It's a verrry basic example, I hope it is of use to you.
I ended using nested MasterPages as my UserControls (as they inherit from UserControl anyway). Then I just call this.LoadControl("~/mp.master") and voila, I have nested UserControls with full design-time support. :)
Related
My page contains several web user controls. Those controls contains other child controls, and those contains more child controls and so on. From my page, I want to be able to access those controls, like I do with other public classes: uc1.uc1_child1.uc1_child1_child1.Update();
(I do know about the FindControl method, and thats what Im currently using. It's however not type safe, and I need to lookup the names of the controls all the time to be on safe side. Much more time consuming than intellisense)
If you create a public property on your usercontrol for each of the usercontrols it contains, that should work.
eg
public SpecificUserControlType ContainedUserControl
{
get
{
return this.uc1_child;
}
}
How dan I dynamically create some public properties on a custom webcontrol.
For example, web control has 5 TextBox controls. I need a public property for each TextBox control to be able to set a specific property of the TextBox control.
I want to be able to loop the controls in the webcontrol and create a public property for each TextBox control.
any ideas?
Edited:
If the child-controls are present at Design-Time then you need to explain why you want to dynamically add properties to access the control members--unless there is a good reason it just sounds like a poor design.
Here's my suggestion:
Leave your controls as Friend or Private -- don't expose them directly (it leads to tight-coupling and gets nasty over time).
Expose a new public property that gets/sets the corresponding property on 1x of your controls; so if you want to set .Text on 5x TextBoxes you'll have 5x properties.
Be done with it.
If you're trying to be clever by dynamically adding them, then it's a good intention that will lead to poor results. Just remember: KISS (Keep it simple, stupid!).
You could create a property like this
private TextBox[] textBoxes; //declared as a class member variable
public TextBox[] TextBoxes
{
get
{
if (textBoxes == null)
{
textBoxes =(from ctrl in this.Controls.OfType<Control>()
where ctrl is TextBox
select (TextBox)ctrl).ToArray();
}
return textBoxes;
}
}
Exposing the controls contained in a WebContol (or any class for that matter) is not a good design as it makes your code brittle and hard to maintain. You should put code that directly manipulates the TextBoxes inside the WebControl.
When a control is added to an UpdatePanel, it can still be accessed from the code behind of the containing page. How is this achieved? Can custom control developers do the same?
In other words, if I develop a template control using the ITemplate Interface, is there a way to wire it up (like the UpdatePanel seems to) so that any controls contained within (declaratively) can be accessed from the containing page also?
You can add a TemplateInstanceAttribute on your ITemplate property to achieve this, it has the effect of promoting the controls to page level:
[TemplateInstance(TemplateInstance.Single)]
public ITemplate AnonymousTemplate {
get { ... }
set { ... }
}
From MSDN:
The TemplateInstanceAttribute class allows you to mark a template property as one that allows single or multiple instantiations. A template that only allows a single instantiation can have the controls that are contained inside of it referenced. The ZoneTemplate property is an example of a property that can be instantiated only one time.
I am trying to create a general class, in which all my ASP.Net pages inherit from so I can share functions across multiple pages.
To do this I would create a new class which inherits from System.Web.UI.Page (the content pages need to inherit this), and then my content pages would inherit the newly create class.
My problem is that the Masterpage inherits from System.Web.UI.Masterpage.
How can I set up my project so both content pages and Masterpage and use functions from the general class?
Please don't hesitate to ask if I am unclear!
Thanks!
E
First, not sure why you'd want to do this. By their function Master Pages should mostly have functions that your Pages shouldn't be concerned with and visa versa. And if you just need some common functionality that isn't page dependent you can just create a static class (much like Math) or a helper class of some kind that you can implement in MasterPage and Page custom base classes.
But your only real option is to create two custom base classes. One that inherits MasterPage and the other from Page. Both will need to implement an interface ICommon which you create. Then create another static class that you can proxy all the functions to.
Yucky solution but it's the only one I can think of.
EDIT
Here's a better solution
public class Helper
{
public static int getUserID(...)
{
// ... Code to get User ID
}
}
In your masterpages and pages use
int UserID = Helper.getUserID(...);
I don't think you can do this, the MasterPage inherits UserControl and Page inherits TemplateControl. Like Spencer said, I would just create a Helper/Utility class.
I know It's too late, but just want to share some one might come across the same.
This is a sample code using Extension functions:
public static void Commonfunction(this TemplateControl ctl)
{
// Your Code here
}
Call this function as
this.Commonfunction();
in any Page or MasterPage.
Although the question is 5 years old, I wanted to share another option for future readers.
From what you explained, I suppose that what you call MasterPage is like a frame which loads the content page on a side of the screen, for example.
If I'm right, you can create a BaseMasterPage class with your functionality and then create a MasterPage for your content pages (which you could also use to place some of the code from your current pages). Next step is obviously to make both your current MasterPage and, let's say, ContentMasterPage inherit from this BaseMasterPage.
So this way you can end up having, for example, a LoggedUser property in both your frame page and content pages.
Does anyone know of a good tutorial that demonstrates using an existing AJAX control extender in a Custom ASP.NET Server Control?
I do not want to build a "Custom AJAX Server Control". I want to build a Custom Server Control that uses an existing AJAX control extender.
I would like to combine an asp:TextBox, asp:ImageButton, asp:CustomValidator (with client side javascript from an embedded resource), and an ajax:CalendarExtender into one custom server control. Or has this already been created?
Any help would be greatly appreciated. Thanks.
UPDATE: Basically, I would like to create a CompositeControl that has an ajax:CalendarExtender as a child control.
Sounds like what you're after is a composite control. They are pretty much exactly like a user control only instead of using the ascx file to create the controls you create them all programmatically. The big advantage of doing this over using a user control is you end up with something you can put in an assembly and use in different projects.
A composite control can inherit from either Control or WebControl. I personally usually find Control more useful to inherit from because I usually don't need a lot of the extra stuff you get from WebControl such as the styling properties since I usually just style through a single CssClass property.
You'll also need to make sure your class implements the INamingContainer interface. This will make sure that each child control will automatically get a unique name if the control is used multiple times in the same parent container.
The most important thing to do when creating a composite control is to override Control's CreateChildControls method. All the logic for actually creating the controls should go in here. The framework will automatically make sure that this gets called at the right time in the page lifecycle.
Here's a little example:
public class MyCompositeControl : Control, INamingContainer
{
protected override void CreateChildControls()
{
Controls.Clear();
var textbox = new TextBox();
textbox.ID = "TextBox1";
Controls.Add(textbox);
if (!Page.IsPostBack || !IsTrackingViewState)
{
// make sure you set the properties after
// you add it to the parent or the viewstate
// won't save properly
textbox.MaxLength = 30;
}
var button = new Button();
button.ID = "Button1";
Controls.Add(button);
if (!Page.IsPostBack || !IsTrackingViewState)
{
button.Text = "Save";
}
}
}
I don't think ASP.NET AJAX should complicate this much. The only thing I can think of ist you'll need to make sure that you create a ScriptManager on whatever page the composite control will be added to.
There's a full example of this on the MSDN site. There's another nice example on this blog.
What you want is to build a user control and not a custom control most probably. A user control is a composite control whereas a custom control is a control built either from the ground up either derived from a basic control.
I would suggest you search on MSDN. I have seen several good articles about that topic in their magazines over the last year or two, that have been fairly thorough. But I don't have links to them and I'm too lazy to Google for you. :\