4

私は自分の WinForms デザイナーを開発しています。既存のカスタム フォーム タイプをロードできる必要があります。私が遭遇した問題の 1 つは、既定の ctor のないフォームです。私のコードは現在、既定の ctor を必要とするデザイナにフォームをロードする前にフォームをインスタンス化しています。

OTOH、VS2008はそのようなフォームをロードできます。実際にはフォームをインスタンス化しないと思います(この質問に記載されているように):デフォルトのctorでさえ実行されません。そして、それは本当に InitializeComponent() を実行しません。その関数にメッセージボックスを追加したところ、表示されません。

カスタムフォームタイプを動的に模倣し、関連すると思われる InitializeComponent のコードの一部のみを実行するように見えます。

VS デザイナーの仕組みに関する詳しい情報がどこにあるか知っている人はいますか?

ティア。

注:満足のいく答えが得られないこの関連する質問を見つけました

編集: 追加情報: Steve は非常に興味深い CodeDom を教えてくれました。私の問題は、デザイナーに読み込む必要がある型が、ソース コードとして利用できるのではなく、既にコンパイルされていることです。CodeDom デシリアライゼーションをコンパイル済みコードに適用する方法が見つかりません。

4

2 に答える 2

13

ここでこれを見つけました:

VS で新しい Windows アプリケーション プロジェクトを開くと、Form1 という空のフォームがデザイン ビューに表示されます。まだプロジェクトをビルドしていないので、デザイナーはどのようにして Form1 のインスタンスを作成し、それを表示できるのでしょうか? さて、デザイナーは実際には Form1 をインスタンス化していません。Form1 の基本クラス、つまり System.Windows.Forms.Form のインスタンスを作成しています。オブジェクト指向プログラミングの基本的な知識があれば、これが直感的に理にかなっていることがわかります。Form1 をデザインするときは、基本クラスの Form から始めて、それをカスタマイズします。これはまさにデザイナーがあなたを助けるものです。

ここで、一連のコントロールをフォームに追加して、デザイナーを閉じたとします。デザイナーを再度開いても、コントロールはまだそこにあります。ただし、基本クラス Form にはこれらのコントロールがありません。したがって、デザイナーが Form1 のコンストラクターを実行していない場合、コントロールはどのように表示されるのでしょうか? デザイナーは、InitializeComponent でコードを逆シリアル化することでこれを行います。デザイナーがサポートする各言語には、InitializeComponent 内のコードを解析し、その CodeDom 表現を作成するパーサーを提供する責任を負う CodeDomProvider があります。次に、デザイナーは一連の CodeDomSerializers を呼び出して、これを実際のコントロール (より広義にはコンポーネント) に逆シリアル化し、デザイン時のフォームに追加できるようにします。さて、私はその説明で多くの詳細を説明しましたが、ただし、ここで重要なのは、Form1 のコンストラクターと InitializeComponent が実際に呼び出されることはないということです。代わりに、デザイナーは InitializeComponent のステートメントを解析して、どのコントロールをインスタンス化してフォームに追加するかを判断します。


上記は、Visual Studio の Windows フォーム デザイナーがフォームを読み込む方法です。あなたが探しているのが、デフォルトのコンストラクターを持たず、含まれているコンポーネント/コントロールにアクセスできるフォームのインスタンスを作成する方法である場合私は解決策を知りません。私が知っている唯一の方法は、デフォルトのコンストラクターの欠如をバイパスできるようにすることですFormatterServices.GetUninitializedObjectですが、注意してください...

オブジェクトの新しいインスタンスはゼロに初期化され、コンストラクターは実行されないため、オブジェクトは、そのオブジェクトによって有効と見なされる状態を表していない可能性があります。

私も、コンパイルされたフォームのインスタンス化を必要とするアプリを持っていますが、常にActivator.CreateInstanceを使用しており、他の開発者が自分のアプリでフォームにアクセスできるようにする場合は、少なくともプライベートのデフォルト コンストラクターを含める必要がありました。私たちはコードベース全体を所有しており、誰もが要件を認識しているため、これは問題ではなく、うまく機能しています。

于 2009-05-16T14:45:47.863 に答える
0

Steve の回答に加えて、新しい Windows フォームをプロジェクトに追加しても抽象化しても、デザイナーで開くことができます。ただし、別のフォームを追加して最初の (抽象) フォームから派生させると、デザイナーでフォームを開こうとするとエラーが発生します。

于 2009-05-16T14:49:11.477 に答える