2016-08-01 7 views
0

インターネットで問題の正確な解決策を見つけることができなくなったので、この質問をしています。あなたが私を助けてくれることを願っています。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のタイプ)
  • 説明(文字列のタイプ)
  • 容量(int型)

することはそれだけでValueメンバーを表示することは可能ですPropertyGridにはMyFieldのプロパティがありますか?

以下は、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しか表示されないようにしたい場合は、01にコンストラクタを追加するだけですので、あなたが他の2つの値を割り当てるので、

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


2のようにprivateにパブリックプロパティを変更することができます(これはあなたのPropertyGridのからMyFieldを非表示になります)
はそうのようFielTypeToString()メソッドをオーバーライドします

public override string ToString() 
{ 
    return Value; 
} 

MyFieldをプライベートに設定し、カプセル化します。インスタンスを文字列として返します。オーバーライドされた値を使用します。あなたのMyFieldが値を返す上書きToString値を返しますので、

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

よう 。

+0

'パブリック文字列値{get {return MyField;};}' - コンパイル時にエラーが発生すると思います – 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

好ましくは部分的にそのプロパティを定義しますクラス。
•クラスのコードにアクセスできる場合は、このオプションを使用します。それらのクラスがあなたのものでない場合は、3番目のソリューションを使用してください。

解決策2 - 利用ExpandableObjectConverterを

あなたはExpandableObjectConverterItemクラスのMyFieldプロパティを飾ることができます。また、あなたがしたい場合はプロパティグリッドでそれを隠すためにFieldTypeクラスの[Browsable(false)]FieldTypeを飾る:

[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があなたでない場合は、このオプションを使用します。それらのクラスがあなたのものであり、コードを変更できる場合は、最初のソリューションを使用します。

関連する問題