プロパティとして aを使用して WinForms ユーザーコントロールを作成しようとしてCollection<T>
います (ここで、T はいくつかのカスタム クラスを表します)。このトピックについてはすでに多くのことを読んでいますが、設計時にこれを適切に機能させることはできません (実行時にはすべて正常に機能します)。より正確に言うと、プロパティ ウィンドウの [...] ボタンをクリックすると、コレクション エディターが正常に表示され、アイテムを追加および削除できます。しかし、[OK] ボタンをクリックしても何も起こらず、コレクション エディターを再度開くと、すべてのアイテムが失われます。デザイナー ファイルを見ると、構成されたコレクションではなく、プロパティが null に割り当てられていることがわかります。最も重要なコードを示します。
ユーザーコントロール:
[Browsable(true),
Description("The different steps displayed in the control."),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor(typeof(CustomCollectionEditor), typeof(UITypeEditor))]
public StepCollection Steps
{
get
{
return wizardSteps;
}
set
{
wizardSteps = value;
UpdateView(true);
}
}
StepCollection クラス:
public class StepCollection : System.Collections.CollectionBase
{
public StepCollection() : base() { }
public void Add(Step item) { List.Add(item); }
public void Remove(int index) { List.RemoveAt(index); }
public Step this[int index]
{
get { return (Step)List[index]; }
}
}
ステップクラス:
[ToolboxItem(false),
DesignTimeVisible(false),
Serializable()]
public class Step : Component
{
public Step(string name) : this(name, null, StepLayout.DEFAULT_LAYOUT){ }
public Step(string name, Collection<Step> subSteps) : this(name, subSteps, StepLayout.DEFAULT_LAYOUT){ }
public Step(string name, Collection<Step> subSteps, StepLayout stepLayout)
{
this.Name = name;
this.SubSteps = subSteps;
this.Layout = stepLayout;
}
// In order to provide design-time support, a default constructor without parameters is required:
public static int NEW_ITEM_ID = 1;
public Step()
: this("Step" + NEW_ITEM_ID, null, StepLayout.DEFAULT_LAYOUT)
{
NEW_ITEM_ID++;
}
// Some more properties
}
カスタム コレクション エディター:
class CustomCollectionEditor : CollectionEditor
{
private ITypeDescriptorContext mContext;
public CustomCollectionEditor(Type type) : base(type) { }
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
mContext = context;
return base.EditValue(context, provider, value);
}
protected override object CreateInstance(Type itemType)
{
if (itemType == typeof(Step))
{
Step s = (Step)base.CreateInstance(itemType);
s.parentContext = mContext; // Each step needs a reference to its parentContext at design time
return s;
}
return base.CreateInstance(itemType);
}
}
私がすでに試したこと:
- ここで説明されているように Step クラスをコンポーネントにする: http://www.codeproject.com/Articles/5372/How-to-Edit-and-Persist-Collections-with-Collectio
Collection<Step>
System.Collections.CollectionBase を継承するカスタム コレクション クラスへの変更StepCollection
(以前のコード プロジェクトの記事でも説明されています)- ここで説明するように、DesignerSerializationVisibility を Content に設定します。Content に設定されている場合、デザイナーは何も割り当てません。
- 私もこれを見つけました:デザイン時に編集できるコレクションを使用して UserControl を作成する方法は? しかし、 CollectionBase クラスはすでにこれを行っています。
- いろいろとデバッグしていますが、例外がないので何が悪いのかさっぱりわかりません。コレクション フォームの終了イベントにイベント リスナーを追加すると、コレクション エディターでいくつかのステップを追加しても、(コレクション フォームの) EditValue プロパティが null のままであることがわかりました。しかし、それがなぜなのかは私にもわかりません...
この投稿を終えたときに、次のトピックを見つけました: DesignMode でコレクションを編集する最も簡単な方法は? 私が経験したのとまったく同じ問題ですが、標準コレクションを使用していないため、提案された回答を使用できません。