Code 'n' Stuff - An occasional series of handy bits of code and techniques that I've found useful in ASP.NET, VB.NET, C#, PHP, Javascript, and many, many more!

Getting your custom control to show other controls as properties (ASP.NET) (20/11/2008)

When developing custom controls In ASP.NET, it's sometimes necessary to include a reference to another control on the form or page. Examples of this are the 'AssociatedControlID' of the Label control, or the 'ControlToValidate' property of the validation controls. If you're using a visual designer such as VWD, or VS, it's handy to be able to select the relevant control from a list.

So, how would you do this for your own custom developed controls?

It would make sense to create a property on your control that is of the type that you want to reference. Perhaps something like this:

public MyCustomControl LinkedControlID {get; set; }

However, while this looks like it does the job in the designer, it won't compile, since the ASP.NET page builder will take the string representation of the linked control's ID and try to create an instance of the object from it. You'll end up with an error like this:

Cannot create an object of type 'MyCustomControl' from its string representation 'MyCustomControl1' for the 'LinkedControl' property.

What we need is a way of selecting a given control on the page while in the designer, which returns a string representation of the control's ID. We can do this by setting the TypeConverter attribute against the property. According to the MS documentation, TypeConverter provides a unified way of converting types of values to other types, as well as for accessing standard values and subproperties. In this case, we'll use a specialised TypeConverter to return the IDs of the controls on the page.

To see how to link to any other control on the page, we can look at how the Label control does it. This uses a TypeConverter of AssociatedControlConverter, which returns a list of all other controls on the page which make sense to be linked to a Label, ie: all controls that are descended from WebControl.

[TypeConverter(typeof(AssociatedControlConverter))]
public string AssociatedControlID { get; set; }

AssociatedControlConverter descends from ControlIDConverter which returns a list of all controls, including the page and the form. AssociatedControlConverter overrides the FilterControl method, which is exactly what we'll do in order to link to other instances of our custom control. If FilterControl returns true, the control appears in the list in the designer, so all we have to do is check that the type of the control supplied to FilterControl is the type of control we're interested in.

To demonstrate how this all works together, imagine a custom control that duplicates the text of any label control it's associated with. We'll need to create a TypeConverter that descends from AssociatedControlConverter and filters out all but Label controls. Then we need to apply this as an attribute to the property of our control that contains the linked label's ID:

public class MyCustomControl: WebControl
{    
    [TypeConverter(typeof(MyCustomControlConverter))]
    public
string LinkedLabelID { get; set ; }
   
    protected
override void Render(HtmlTextWriter writer)
    {
        if
(LinkedLabelID != "")
        {
            Label
lbl = (Label)Page.FindControl(LinkedLabelID);
            // do something with the linked label here ...

        }
        else

        {
            writer.Write("[" + ID + "]"); 
        } 
       
base.Render(writer); 
    }
}

public
class MyCustomControlConverter : AssociatedControlConverter
{
    protected
override bool FilterControl(Control control)
    { 
        return (control.GetType() == typeof(Label));
    }
}

As you can see, the FilterControl method of the MyCustomControlConverter only returns true of the type of the supplied control is Label. Replacing Label with something else allows us to change it so we can refer to any other control we may be interested in.

You can download a sample control that shows this behaviour here (in VB & C#, zipped)

References:

MSDN - ControlIDConverter.FilterControl Method

 

 

 
  | +44 (0)8456 430 187 | ccinfo@coderscollective.com | 
All site content
© coderscollective.pz 2008