I think I've found the solution now.
Running the following from inside a Page_Load event gave me the Resource class names:
String[] resourceClassNames = (from type in assembly.GetTypes()
where type.IsClass && type.Namespace.Equals("Resources")
select type.Name).ToArray();
So I thought I'd be able to do something similar from inside the GetResourceFileNames(ITypeDescriptorContext context) function of the TypeConverter, using the context parameter to get hold of the correct assembly. Unfortunately, I could only seem to get the Custom Control's assembly or the System.Web assembly.
So, instead I've created a UITypeEditor which has an IServiceProvider passed into the EditValue routine. From this I was able to create an instance of ITypeDiscoveryService which I then used to get all of the types from the correct assembly:
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
// Check if all the expected parameters are here
if (context == null || context.Instance == null || provider == null)
{
// returning with the received value
return base.EditValue(context, provider, value);
}
// Create the Discovery Service which will find all of the available classes
ITypeDiscoveryService discoveryService = (ITypeDiscoveryService)provider.GetService(typeof(ITypeDiscoveryService));
// This service will handle the DropDown functionality in the Property Grid
_wfes = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
// Create the DropDown control for displaying in the Properties Grid
System.Windows.Forms.ListBox selectionControl = new System.Windows.Forms.ListBox();
// Attach an eventhandler to close the list after an item has been selected
selectionControl.SelectedIndexChanged += new EventHandler(selectionControl_SelectedIndexChanged);
// Get all of the available types
ICollection colTypes = discoveryService.GetTypes(typeof(object), true);
// Enumerate the types and add the strongly typed
// resource class names to the selectionControl
foreach (Type t in colTypes)
{
if (t.IsClass && t.Namespace.Equals("Resources"))
{
selectionControl.Items.Add(t.Name);
}
}
if (selectionControl.Items.Count == 0)
{
selectionControl.Items.Add("No Resources found");
}
// Display the UI editor combo
_wfes.DropDownControl(selectionControl);
// Return the new property value from the UI editor combo
if (selectionControl.SelectedItem != null)
{
return selectionControl.SelectedItem.ToString();
}
else
{
return base.EditValue(context, provider, value);
}
}
void selectionControl_SelectedIndexChanged(object sender, EventArgs e)
{
_wfes.CloseDropDown();
}
This seems to work well although I expect there's a more stylish way to get the types required using LinQ, but I've only just started looking at LinQ and I can't seem to get the correct syntax when querying against a collection rather than an array as in the earlier example.
If anyone can suggest the LinQ syntax that would do this or indeed, a better way of accomplishing the whole thing, then it would be most welcome.