Решение 1 - Добавить свойство
Вы можете добавить свойство Item
класса, чтобы получить и установить MyField.Value
:
public string Value
{
get
{
if (MyField != null)
return MyField.Value;
return null;
}
set
{
if (MyField != null)
MyField.Value = value;
}
}
• Предпочтительно определить, что свойство в частичной класс.
• Используйте этот параметр, если у вас есть доступ к кодам классов. Если эти классы не принадлежат вам, используйте третье решение.
Решение 2 - Использование ExpandableObjectConverter
Вы можете украсить MyField
свойство Item
класса с ExpandableObjectConverter
. Также украшают FieldType
с [Browsable(false)]
из FieldType
класса, чтобы скрыть его в собственность сетке, если вы хотите:
[TypeConverter(typeof(ExpandableObjectConverter))]
public FieldType MyField { get; set; }
• Для того, чтобы настроить текст, который показан перед MyField
, вы можете переопределить ToString
метод FieldType
и вернуть Value
. Также вы можете сделать это с помощью пользовательского TypeConverter
и переопределить его метод ConvertTo
.
Решение 3 - Использование пользовательских TypeDescriptor
Это не так просто, как первое решение, но вывод полностью, как то, что вы получите, используя первое решение. Он подходит для случаев, когда вы не можете манипулировать этими классами.
Вы можете использовать его таким образом:
var item = new Item() { MyField = new FieldType() { Value = "Some Value" } };
TypeDescriptor.AddProvider(new MyTypeDescriptionProvider(), item);
this.propertyGrid1.SelectedObject = item;
Или украшая Item
класс с:
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class Item
настраиваемое свойство Descriptor
public class MyPropertyDescriptor : PropertyDescriptor
{
private PropertyDescriptor subProperty;
private PropertyDescriptor parentProperty;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor sub)
: base(sub, null)
{
subProperty = sub;
parentProperty = parent;
}
public override bool IsReadOnly { get { return subProperty.IsReadOnly; } }
public override void ResetValue(object component)
{
subProperty.ResetValue(parentProperty.GetValue(component));
}
public override bool CanResetValue(object component)
{
return subProperty.CanResetValue(parentProperty.GetValue(component));
}
public override bool ShouldSerializeValue(object component)
{
return subProperty.ShouldSerializeValue(parentProperty.GetValue(component));
}
public override Type ComponentType { get { return parentProperty.ComponentType; } }
public override Type PropertyType { get { return subProperty.PropertyType; } }
public override object GetValue(object component)
{
return subProperty.GetValue(parentProperty.GetValue(component));
}
public override void SetValue(object component, object value)
{
subProperty.SetValue(parentProperty.GetValue(component), value);
OnValueChanged(component, EventArgs.Empty);
}
}
Пользовательский тип дескриптора
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor original;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor)
: base(originalDescriptor)
{
original = originalDescriptor;
}
public override PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(new Attribute[] { });
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = original.GetProperties().Cast<PropertyDescriptor>().ToList();
var parent = properties.Where(x => x.Name == "MyField").First();
var sub = TypeDescriptor.GetProperties(typeof(FieldType))["Value"];
properties.Remove(parent);
properties.Add(new MyPropertyDescriptor(parent, sub));
return new PropertyDescriptorCollection(properties.ToArray());
}
}
Пользовательские TypeDescriptorProvider
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType,
object instance)
{
ICustomTypeDescriptor baseDes = base.GetTypeDescriptor(objectType, instance);
return new MyTypeDescriptor(baseDes);
}
}
• Используйте эту опцию, если Item
и FieldType
не ваши. Если эти классы принадлежат вам, и вы можете изменить их код, используйте первое решение.
Вы можете контролировать, что и как отображается, создав оболочку. Типичным приложением является преобразование всех свойств, скрытие некоторых, переключение во время выполнения и т. Д. Но самый простой ответ заключается в использовании атрибута [[Browsable (false)] '. – Sinatr