Monday, March 19, 2012

Mimic the rowcount Transform''s variables dropdown?

I'm trying to mimic the rowcount transform's custom property called VariableName in a custom pipeline transform, with the same drop-down and list of variables in the default property grid as that of "RowCount".

Should a UITypeEditor or a TypeConverter be used for such a custom property? More importantly, in either case, how do you get from the UITypeEditor or TypeConverter to the TaskHost which contains the Variables to enumerate?

I'm not that familiar with Windows Forms, but it appears in both cases (editor or type converter), an ITypeDescriptorContext parameter named "context" is passed, but I'm certain how to get from A to B, that is, from the context variable to the TaskHost.

P.S. There's no need to add a new variable, just select from those that already exist.

Either a UITypeEditor or a TypeConverter could be used. I like the greater flexibility of a UITypeEditor for most things myself, but from memory I required one to give the better UE when creating variables, so as you just want to select, a TypeConverter should suffice and might be marginally simpler.

What type is context? What types are the properties of context, things like InnerObject? Examine what you are given, either context or a property of context will get you to where you need to be. It varies slightly depending on the host, the advanced UI or the property grid.

|||

It would seem like the appropriate route to use to mimic the VariableName drop-down in the RowCount transform would be to use IDTSPipelineEnvironmentService in a TypeConverter, which allows you to retrieve a component's TaskHost and its Variables collection.


But, I cannot find a way to get an IDTSPipelineEnvironmentService from within a TypeConverter on the Advanced Editor's property grid. Would you not agree that IDTSPipelineEnvironmentService is the way to get at the TaskHost from a transform's advanced editor, since that service is documented in BOL?

So I ended up using reflection (see the following Type Converter), which operates "correctly" ( creates a drop-down of variables' names) ... but the retrieval of a TaskHost and its Variables collection through reflection on non-public properties is not documented.

Code Snippet

// TaskHost scoped Variables for use in

// Pipeline Component's Advanced Editor (dropdown)

public sealed class VariablesConverter : TypeConverter

{

static StandardValuesCollection svc =

new StandardValuesCollection(new ArrayList());

public override bool

GetStandardValuesSupported(ITypeDescriptorContext context)

{

return true;

}

public override StandardValuesCollection

GetStandardValues(ITypeDescriptorContext context)

{

TaskHost th = null;

PropertyInfo tashHostProperty = null;

List<string> values = new List<string>();

if (context == null) { return svc; }

if (context.Instance == null) { return svc; }

tashHostProperty = context.Instance.GetType().GetProperty(

"PipelineTask", typeof(TaskHost));

// a => b ( Component => TaskHost via reflection ? )

if (tashHostProperty == null) { return svc; }

th = tashHostProperty.GetValue(context.Instance, null) as TaskHost;

if (th == null) { return svc; }

foreach (Variable v in th.Variables)

{

if (!v.SystemVariable && v.DataType == TypeCode.String)

{

values.Add(v.QualifiedName);

}

}

values.Sort();

return new StandardValuesCollection(values);

}

}


|||

I don't have a problem with the way it works, and it makes sense for the context to be as it is, rather than the IDTSPipelineEnvironmentService, but what is not documented is the type of context in the different hosts where you could be expected to provide editors or converters, such as the Advanced UI or the normal properties grid.

A custom UI will be friendlier still, although having the editor is no bad thing as well.

|||

Alright, I appreciate your insight on this one (about looking into ALL the properties on the ITypeDescriptorContext object ) when building UI widgets on the Advanced Editor.

In terms of friendliness, I'm starting to think its more "friendly" from a development perspective to build a custom UI for components/tasks/enumerators, since with a custom UI you're handed explicit references to service providers, and to relevant collections (like variables and connections)... and the documentation and examples generally use/describe custom UI development over use of the pre-provided Advanced Editor.

In any case, I went out and got a Windows forms book... of course, that may not be long for the world what with the 3.0 .NET Framework's WPF.

No comments:

Post a Comment