Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This is the fourth in my blog series on Visual Studio 2010 Designer Multi-Targeting
As mentioned in my previous post, the property grid filtering is implemented through the use of a TypeDescriptionProvider which reflects against the project’s target framework. This multi-targeting provider is attached automatically (via TypeDescriptor.AddProvider) for Windows and Web Forms controls that are created on or added to the design surface. The following are where these automatic hook-ups take place:
WebForms:
ControlBuilder.BuildObject – covers controls created when switching from source to design view and controls added from the toolbox.
AddControlToDocument – covers controls manually created and added to the design surface.
WinForms:
DesignSurface.CreateInstance – covers controls created when the designer is opened (controls deserialized from the source code), and controls added from the toolbox.
[Component.]Container.Add (where component is directly on the design surface) – covers controls manually created and added to the design surface through a parent component.
Control vendors should be aware that these hook-ups do not cover any child controls created manually by the root control itself, unless they are explicitly added to the design surface. However, these only need to be multi-targeting aware if any designer UI is affected by the metadata (properties, attributes, etc) from these child controls.
If necessary, you can manually hook-up a multi-targeting provider to a child control or other object by using the TypeDescriptionProviderService to create the provider:
var mtService = (TypeDescriptionProviderService)serviceProvider.GetService(typeof(TypeDescriptionProviderService));
if (mtService != null) {
var mtProvider = mtService.GetProvider(_childControl);
TypeDescriptor.AddProvider(mtProvider, _childControl);
}
Note that TypeDescriptor does not publicly expose any providers in its providers list -- TypeDescriptor.GetProvider returns a node that wraps the actual provider. If you need to check whether a multi-targeting provider has already been attached to a control or object instance, then you will need to rely on behavior from the multi-targeting provider. It just so happens that the multi-targeting provider is injecting a ProjectTargetFrameworkAttribute onto its reflection types, which can be used to detect the provider’s existence:
var type = TypeDescriptor.GetProvider(_childControl).GetReflectionType(typeof(object));
if (!type.IsDefined(typeof(ProjectTargetFrameworkAttribute), false)) {
// multi-targeting provider is NOT attached
}