Я думаю, что нашел решение сейчас.
Запуск следующего изнутри события Page_Load дал мне имена классов ресурсов:
String[] resourceClassNames = (from type in assembly.GetTypes()
where type.IsClass && type.Namespace.Equals("Resources")
select type.Name).ToArray();
Поэтому я подумал, что смогу сделать нечто подобное изнутри функции GetResourceFileNames (контекст ITypeDescriptorContext) TypeConverter, используя параметр context, чтобы получить правильную сборку. К сожалению, я мог только получить сборку пользовательского элемента управления или сборку System.Web.
Итак, вместо этого я создал UITypeEditor, в котором IServiceProvider передан в процедуру EditValue. Из этого я смог создать экземпляр ITypeDiscoveryService, который затем использовал для получения всех типов из правильной сборки:
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();
}
Кажется, это работает хорошо, хотя я ожидаю, что есть более стильный способ получения типов, требуемых с помощью LinQ, но я только начал изучать LinQ и не могу получить правильный синтаксис при запросах к коллекции а не массив, как в предыдущем примере.
Если кто-нибудь может предложить синтаксис LinQ, который бы сделал это, или действительно, лучший способ выполнения всего этого, то это было бы очень кстати.