我想我现在已经找到了解决方案。
从 Page_Load 事件中运行以下内容给了我 Resource 类名称:
String[] resourceClassNames = (from type in assembly.GetTypes()
where type.IsClass && type.Namespace.Equals("Resources")
select type.Name).ToArray();
所以我想我可以从 TypeConverter 的 GetResourceFileNames(ITypeDescriptorContext context) 函数内部做类似的事情,使用 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 语法,或者确实是完成整个事情的更好方法,那么它将是最受欢迎的。