是否可以修改ComponentConverter
,Typeconverter
,...以便我可以选择表单外的静态类中的“组件”?
当我创建自定义控件并添加Component
或Control
类型的属性时,我会在设计器中找到一个下拉菜单,我可以在其中选择一个现有控件。
对所选对象的引用会自动添加到设计器代码中。
问题是,下拉列表只允许我选择在此表单中声明的组件或此表单继承的表单,但不包括其他表单或静态类。
但是我希望在我的解决方案中有一个特定的文件,我可以在一段时间内声明所有这些组件,然后在设计时在每个表单中使用它们(我的项目中有几个)。
当我在设计器代码中自己添加对静态对象的引用时,一切正常,但这并不舒服,因为我必须手动更改代码。
是否可以修改Converter
或UITypeEditor
,以便它可以选择静态对象然后将它们传递给设计师?
我试图覆盖ComponentConverter,但在设计器代码中它只写“null”而不是对象:
class MyConverter : ComponentConverter
{
public MyConverter(Type type) : base(type)
{
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new List<BOOL>() { Variablen.M0_2, Variablen.M0_3, Variablen.M0_4 });
}
}
答案 0 :(得分:0)
经过一些工作,我得到了这个工作,但稳定性并不是最好的。有时在编译之后我会收到错误,因为TypeConverter
基类:
[TypeConverter(typeof(MyReferenceTypeonverter))]
[DesignerSerializer(typeof(MyObjectSerializer), typeof(CodeDomSerializer))]
public abstract class MyReferencableObject
{
internal FieldInfo FieldInfo { get; set; }
//Could also use: FieldInfo.DeclaringType.FullName + "." + FieldInfo.Name;
public string FullName { get { return FieldInfo.DeclaringType.Name + "." + FieldInfo.Name; } }
}
串行:
public class MyObjectSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager, object value)
{
return new CodeVariableReferenceExpression((value as MyReferencableObject).FullName);
}
}`
容器
/// <summary>
/// Prototype for class that whrer MyReferencableObject are declared
/// </summary>
public abstract class Deklaration
{
}
的TypeConverter
public class MyReferenceTypeonverter : TypeConverter
{
private Type ContainerType = typeof(Deklaration);
private const string empty = "(none)";
Dictionary<string, MyReferencableObject> values;
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string FullName = (string)value;
if (FullName == empty)
return null;
InitDict(context);
if (values.ContainsKey(FullName))
return values[FullName];
return value;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value == null)
return empty;
InitDict(context);
foreach (string key in values.Keys)
if (key != empty)
if (values[key].FullName == ((MyReferencableObject)value).FullName)
return key;
//sometimes happens...
return "ERROR!!!";
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
InitDict(context);
return new StandardValuesCollection(values.Values);
}
void InitDict(ITypeDescriptorContext context)
{
//sometimes happens...
if (context == null)
return;
Dictionary<string, MyReferencableObject> tvalues = new Dictionary<string, MyReferencableObject>();
tvalues.Add(empty, null);
ITypeDiscoveryService Service = (ITypeDiscoveryService)context.GetService(typeof(ITypeDiscoveryService));
//sometimes happens...
if (Service == null)
return;
foreach (Type declaration in Service.GetTypes(ContainerType, false))
foreach (FieldInfo fieldInfo in declaration.GetFields())
if (context.PropertyDescriptor.PropertyType.IsAssignableFrom(fieldInfo.FieldType))
{
MyReferencableObject var = (MyReferencableObject)fieldInfo.GetValue(null);
var.FieldInfo = fieldInfo;
tvalues.Add(var.FullName, var);
}
//in a perfect world the if should not be necessary....
if (tvalues.Count > 1 || values == null)
values = tvalues;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return TypeDescriptor.GetProperties(value, attributes);
}
}