2016-08-01 271 views
0

我無法再在Internet中找到我的問題的確切解決方案,因此我正在問這個問題。希望你能幫助我。在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; } 
} 

在我的形式,我創建項目類的一個實例。它包含以下成員:

  • MyField的(類型的FieldType的)
  • 描述(字符串類型)
  • 容量(一個int)

是否有可能只顯示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.(這將隱藏您的PropertyGrid中的MyField
覆蓋的FielTypeToString()方法,像這樣

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

您可以ExpandableObjectConverter裝飾Item類的MyField財產。另外隨着[Browsable(false)]裝飾FieldTypeFieldType類來隱藏它在屬性網格中,如果你想:

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

enter image description here

•要自定義其在MyField前面顯示的文本,可以覆蓋的FieldTypeToString方法並返回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 

自定義屬性描述

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); 
    } 
} 

•使用此選項,如果ItemFieldType是不是你的。如果這些類是您的,並且您可以更改其代碼,請使用第一種解決方案。

相關問題