2016-08-01 3 views
0

Я больше не мог найти точного решения моей проблемы в Интернете, поэтому я задаю этот вопрос. Надеюсь, ты сможешь мне помочь.Dispaying и редактирование дополнительного свойства объекта PropertyGrid

У меня есть следующие классы:

public Item 
{ 
    public FieldType MyField { get; set; } 
    public string Description { get; set; } 
    public int Capacity { get; set; } 
} 

public FieldType 
{ 
    public string Value { get; set; } 
    public string FieldCode { get; set; } 
    public string TableCode { get; set; } 
} 

В моей форме, я создал экземпляр класса Item. Который содержит следующие элементы:

  • MyField (тип FieldType)
  • Описание (тип строки)
  • Емкость (ИНТ)

Можно только показать Value член от MyField Недвижимость в PropertyGrid?

Ниже описано, как присвоить свойство выбранного объекта PropertyGrid.

void Form1(object sender, EventArgs e) 
{ 
    propertyGrid1.SelectedObject = new Item();   
} 
+0

Вы можете контролировать, что и как отображается, создав оболочку. Типичным приложением является преобразование всех свойств, скрытие некоторых, переключение во время выполнения и т. Д. Но самый простой ответ заключается в использовании атрибута [[Browsable (false)] '. – Sinatr

ответ

1

Да, легко:
добавить вычисленное только для чтения свойство Item

public Item 
{ 
    public FieldType MyField { get; set; } 
    public string MyFieldValue => MyField.Value; 
    public string Description { get; set; } 
    public int Capacity { get; set; } 
} 
0

Я не совсем уверен, что вы ищете, но здесь находятся 2 ответов

1. (как Я это понял)
, если вы хотите, чтобы он показывал только Value при попытке просмотреть свойства экземпляра MyField, то все, что вам нужно сделать, это добавить конструктор в MyField так что вы можете назначить другие два значения и изменить общественное свойство private как так

public FieldType 
{ 
    public string Value { get; set; } 
    private string FieldCode { get; set; } 
    private string TableCode { get; set; } 
} 


2. (это скроет MyField от вашего PropertyGrid)
Override в ToString() метод FielType как так

public override string ToString() 
{ 
    return Value; 
} 

затем установите MyField в личный кабинет и инкапсулируйте его. возвращая экземпляр в виде строки. который использовал бы переопределенное значение. как так

private FieldType MyField; 
public string value{ get{return MyField.ToString();}set;} 

ваш MyField возвратит преодолено ToString значение, которое возвращает значение.

+0

'public string value {get {return MyField;} set;}' - Я думаю, что это приведет к ошибке времени компиляции – yonan2236

+0

@ yonan2236 спасибо ... исправлено это – Neil

0

Решение 1 - Добавить свойство

Вы можете добавить свойство Item класса, чтобы получить и установить MyField.Value:

public string Value 
{ 
    get 
    { 
     if (MyField != null) 
      return MyField.Value; 
     return null; 
    } 
    set 
    { 
     if (MyField != null) 
      MyField.Value = value; 
    } 
} 

enter image description here

• Предпочтительно определить, что свойство в частичной класс.
• Используйте этот параметр, если у вас есть доступ к кодам классов. Если эти классы не принадлежат вам, используйте третье решение.

Решение 2 - Использование ExpandableObjectConverter

Вы можете украсить MyField свойство Item класса с ExpandableObjectConverter. Также украшают FieldType с [Browsable(false)] из FieldType класса, чтобы скрыть его в собственность сетке, если вы хотите:

[TypeConverter(typeof(ExpandableObjectConverter))] 
public FieldType MyField { get; set; } 

enter image description here

• Для того, чтобы настроить текст, который показан перед 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 не ваши. Если эти классы принадлежат вам, и вы можете изменить их код, используйте первое решение.

Смежные вопросы