私が使用している多くのカスタム クラスがあり、それらについて説明し、例を投稿します。それらがすべて何をするかを説明した後、バグが発生する条件を明確に説明しようとします。
まず、PropertyGrid を使用して、さまざまな種類のオブジェクトのプロパティを表示しています。PropertyGrid の既定のバインドは、私が望んでいたほど説明的ではなかったため、「表示」クラスと呼ぶカスタム クラスをいくつか作成しました。これらの Display クラスは、オブジェクトを渡し、適切にフォーマットされた文字列と、渡された実際のオブジェクトのパブリック プロパティ (場合によってはメソッド) の説明を返すプロパティを作成することによって構築されます。
いくつかの簡略化されたサンプル コードを使用してこれを示します。
これは、PropertyGrid に表示したいオブジェクトの例です。
public class Joint
{
public Joint(...)
{...}
//properties
public string Name { get; set;}
public CustomObject CC { get; set;}
public List<CustomObject> Custom List { get; set;}
}
文字列プロパティ "Name" は PropertyGrid に正常に表示されますが、CustomObject と List は非常にユーザー フレンドリーに表示されませんでした。
だから私はこのクラスを書くことによって解決策を作成しようとしました:
public class DisplayJoint
{
private Joint _jnt;
public DisplayJoint(Joint jnt)
{
_jnt = jnt;
}
//properties
public string Name { get { return _jnt.Name; } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayCustomObject CC { get { return new DisplayCustomObject(_jnt.CC); } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public List<CustomObject> CustomList { get; set;}
}
上記のコードでわかるように、Joint クラスと CustomObject クラスの両方に特別な DisplayClasses を作成しました。私のプロジェクトには、同じ種類の重複する表示クラス プロパティを必要とする非常に多くの異なる種類のオブジェクトがあります。
上に、最後の 2 つのプロパティの上に追加した行が表示されます。
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
この行は、properGrid で希望する方法で CustomObject を表示するという私の問題を解決します (ほとんど... これについては後で詳しく説明します)。ただし、カスタム リスト プロパティでは同じようには機能しません。カスタム リストでは、カウントと容量 (リストの実際のプロパティ) のみを表示するように展開されます。これは理にかなっていますが、私が望んでいたものではありませんでした。リスト内に実際に含まれているオブジェクトを見たかったのです。
だからここに私の複雑な解決策があります。最初にこの質問から取られました:
プロパティの形式でプロパティ グリッドのバインドされたリストにオブジェクトを動的に追加するために使用している 2 つのクラスがあります。最初の (CustomClass) は、ここからダウンロードできます。プロパティを動的に作成するために使用されます。私が使用している 2 番目のクラス (DisplayIEnumerable) は最初のクラスから派生したもので、ここで見つけることができます。
DisplayIEnumerable クラスはリスト オブジェクトをループ処理し、各オブジェクトに含まれる情報を使用してプロパティを自身に追加します。これらのオブジェクトのプロパティをグリッド内でどのように表現するかを正確に定義するために、DisplayClass が渡されます。
この時点まで、すべてがうまく機能しています!この写真で証明されているように (写真は提供されたクラスを使用して作成されたものではありません。使用しているクラスでは文字列の形式が異なります。関連するコードに集中できるように、書式設定コードを削除しました。
長いイントロの後、本当の質問です。上記の手法を使用して、独自の表示クラスを作成していない CustomObjects を動的に処理できるクラスを作成したいと考えています。このコードは、アプリケーションをテスト用に使用する人のために残して、会社の CustomObjects ごとに完全な表示クラスを用意しなくても、より効果的にテストできるようにするつもりです。(数百あります) 代わりに、propertyGrid を以下のクラスにバインドすることで、リストであるすべてのプロパティと、対応する DisplayClasses をその場所にバインドする CustomObjects を取得したいと考えています。
これは、私がすでに試してバグがあるクラスです。Lists を DisplayIEnumerable クラスに置き換える実装はまだ試していません。基本的な機能を最初に動作させたかったのです。
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
internal class DisplayObject : CustomClass<T>
{
#region Variables
protected T _obj;
#endregion
#region Constructor
public DisplayObject(T obj)
{
if (obj != null)
{
try
{
Type currentType = typeof(T);
foreach (PropertyInfo propertyInfo in currentType.GetProperties())
{
Attribute[] attributes = new Attribute[1];
if (propertyInfo.GetType() is IEnumerable)
attributes[0] = new TypeConverterAttribute(typeof(ExpandableObjectConverter));
else
attributes[0] = null;
this.Add(new CustomProperty(propertyInfo.Name, propertyInfo, propertyInfo.GetType(), false, true, attributes));
}
}
catch
{
MessageBox.Show("Failure!");
}
}
}
#endregion
#region Properties
[Browsable(false)]
public object Item
{
get { return _obj; }
set { _obj = value; }
}
#endregion
}
実行すると、PropertyGrid は次のように表示されます。
ただし、展開矢印をクリックすると、何も起こらず、矢印が消えます。
私の DisplayIEnumerable クラスでは間違っていない上記のクラスの何が問題なのですか?
私はこのようなDisplayObjectクラスを使用しています(DisplayClass内):
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayObject EndJoint { get { if (_member.bcEnd != null) { return new DisplayObject(_member.EndJoint); } else return null; } }
前もって感謝します!誰かがこの問題を解決できれば、私は非常に感銘を受けます。