環境
カスタム ASP.Net Web コントロールのカスタム コレクション エディター/デザイナーに取り組んできました。Web コントロールは奇妙な階層を公開しているため、開発者が簡単に操作できるようにするためにカスタム エディターを使用するのが適切であると思われました。
ASPX コードのビルドと Web コントロールの使用は機能します。つまり、 と のようなものPersistChildren
がParseChildren
処理されます。
Web コントロールのプロパティのシグネチャは次のようになります。
[PersistenceMode(PersistenceMode.InnerProperty)]
[Themeable(false)]
[Browsable(false)]
public virtual DimensionsCollection Dimensions { get; internal set; }
プロパティはパブリックではないことに注意してください。それが公開されている場合、デザイナーのすべての種類がうまくいかないでしょう。DimensionsCollection
を単純に継承するクラスですList<Dimension>
。Dimension
クラス自体は特別なものではなく、いくつかのプロパティを持つものです。
かっこいいと思うからといって、デザイナーのアクションからプロパティを変更できるようにしたいのです。ControlDesigner
そのために、クラスを実装し、 ActionList
. アクションの 1 つに、エディターを開くリンクボタンがあります。
var editor = new Editors.DimensionEditor(control.Dimensions);
if (editor.ShowDialog() == DialogResult.OK)
{ /* SEE BELOW */ }
エディター自体は、List<Dimension>
コンストラクター引数として受け取り、コレクションを変更する Windows フォームです。
問題
このコードを使用すると、エディターが機能し、「デザイナー」ビューでコントロール コレクションが更新されることがわかります。エディタを複数回開くと、状態が変化します。つまり、メモリ内のどこかで状態がエディタによって更新されます。
ただし、ASPX コードに移動すると、次元がなくなっていることがわかります。つまり、一言で言えば、問題は、Visual Studio にプロパティを ASPX ファイルに書き込み/シリアル化/永続化するように指示する必要があることです。(単純に... )
奇妙なことに、私はこれを行う方法をどこにも見つけることができません...たとえノーマルCollectionEditor
がそれを行うことができるように見えても(残念ながらサブクラス化することはできません)
私が試したいくつかのこと
他のプロパティについては、このようなものを使用する必要があることに気付きましたが、これは機能していないようです。コードは、「以下を参照」とマークされたポイントに入力されました。場合によっては、そのポイントから呼び出されたデザイナーのヘルパー コールに入力されました。
PropertyDescriptor pd = TypeDescriptor.GetProperties(base.Component)["Dimensions"];
// use setter with internal property -> no effect
// this.OnComponentChanged(this, new ComponentChangedEventArgs(this.Component, pd, null, newdim)); -> no effect
// use getter to obtain list -> populate that using another list that's created in the editor
なぜうまくいかないのか理解できます。どうやら誰かが Visual Studio にプロパティが変更されたことを伝える必要があるようです...それを行う方法がわかりません。