デザイン時開発のトラブルシューティング
更新 : 2007 年 11 月
Windows フォームのコンポーネントおよびコントロールでカスタムのデザイン時操作を作成する際には、次のような一般的な問題が発生する場合があります。
デザイン時にデバッグできない
コンパイル エラー : "型または名前空間名 '型名' が見つかりませんでした。"
デザイン時エラー : "コンポーネント 'コンポーネント名' を生成できませんでした。"
デバッグ エラー : "有効ではないスレッド間の操作 : コントロールが作成されたスレッド以外のスレッドからコントロール 'コントロール名' がアクセスされました。"
デザイン時エラー : "ファイル内のクラスが視覚的にデザインできるクラスから継承されていないため、このファイル用にデザイナを開くことはできません。"
コンポーネントの削除後にグリフが残る
既定のデザイナの動作がカスタムの動作によって無効になった
デザイナ イベントが予期しない形で発生した
コレクションをシリアル化できない
デザイナが UndoEngine 参照を取得できない
デザイン環境でコンポーネントのプロパティの変更が認識されない
コンポーネントまたはデザイナ変更後のデザイン環境の更新
新しく生成された Windows フォームの FxCop 警告 :DoNotInitializeUnnecessarily
部分クラスおよび Windows フォーム デザイナ
レガシ カスタム コントロールが原因でデザイナで予期しない動作が発生する
ホストされているデザイナのスマート タグによって例外が発生する
コンポーネント アイコンがツールボックスに表示されない
デザイン時にデバッグできない
デザイン時のコードをデバッグするには、次の 2 つの方法があります。
MessageBox.Show 呼び出しをコード内の重要なポイントに配置します。
Visual Studio の別のインスタンスをアタッチして、最初のインスタンスのデザイン環境をデバッグします。
詳細については、「方法 : デザイン時サービスにアクセスする」を参照してください。
Topic | Location |
---|---|
チュートリアル : カスタム Windows フォーム コントロールのデザイン時のデバッグ | Windows フォーム コントロール |
コントロールとコンポーネントの作成時のトラブルシューティング | Windows フォーム コントロール |
チュートリアル : カスタム Windows フォーム コントロールのデザイン時のデバッグ | Windows フォーム コントロール |
コントロールとコンポーネントの作成時のトラブルシューティング | Windows フォーム コントロール |
チュートリアル : カスタム Windows フォーム コントロールのデザイン時のデバッグ | Windows フォーム コントロール |
コントロールとコンポーネントの作成時のトラブルシューティング | Windows フォーム コントロール |
チュートリアル : カスタム Windows フォーム コントロールのデザイン時のデバッグ | dv_mclictl |
コントロールとコンポーネントの作成時のトラブルシューティング | dv_mclictl |
コンパイル エラー : "型または名前空間名 '型名' が見つかりませんでした。"
System.Design アセンブリを参照する必要があります。デザイナ関連の型は、System.Design アセンブリ内にあります。ここには、System.Windows.Forms.Design および System.ComponentModel.Design 名前空間内の型が含まれます。
また、Imports または using キーワードを使用して、必要な名前空間をインポートしてください。詳細については、「方法 : Windows フォームでデザイン時サポートにアクセスする」を参照してください。
デザイン時エラー : "コンポーネント 'コンポーネント名' を生成できませんでした。"
このエラーは、[ツールボックス] からデザイン サーフェイスにコンポーネントまたはコントロールを作成する際に表示されます。このエラーの考えられる 2 つの原因を次の表に示します。
原因 |
説明 |
メモ |
---|---|---|
既定のコンストラクタがない |
コンポーネントまたはコントロールには、既定のコンストラクタ (パラメータのないコンストラクタ) が必要です。 |
デザイン環境では、型のインスタンスを作成するためには既定のコンストラクタが必要です。 |
コンポーネントがジェネリック型 |
コンポーネントまたはコントロールをジェネリック型にすることはできません。この型は、テンプレート型またはパラメータ化された型とも呼ばれます。デザイン環境はジェネリック型をサポートしていません。 |
ジェネリック型が UserControl から派生している場合、それを Visual Studio の [ユーザー コントロール テスト コンテナ] で実行しようとすると、次のエラーが発生します。 UserControl 'name' を作成できませんでした。 コンポーネントおよびコントロールがジェネリック型であることはできませんが、それらがジェネリック型を使用することはできます。 |
デザイン時エラー : "値を null にすることはできません。パラメータ名 : 'コンポーネント名'"
このエラーは、[ツールボックス] からデザイン サーフェイスにコンポーネントまたはコントロールを作成する際に表示されます。最も一般的な原因は、64 ビットのアセンブリに構築されたコンポーネントまたはコントロールを使用しようとしていることです。Visual Studio のデザイン環境では、64 ビットのコンポーネントはサポートされていません。
デバッグ エラー : "有効ではないスレッド間の操作 : コントロールが作成されたスレッド以外のスレッドからコントロール 'コントロール名' がアクセスされました。"
in your Windows フォーム アプリケーションでマルチスレッドを使用する場合は、スレッド セーフな方法でコントロールを呼び出すように注意する必要があります。この例外はデバッガによって発生し、実行時には表示されませんが、この問題が発生した場合には修正することを強くお勧めします。詳細については、「方法 : Windows フォーム コントロールのスレッド セーフな呼び出しを行う」を参照してください。
デザイン時エラー : "ファイル内のクラスが視覚的にデザインできるクラスから継承されていないため、このファイル用にデザイナを開くことはできません。"
コンポーネントまたはコントロールが含まれているファイルには、複数のクラスの定義を含めることができますが、ファイル内の先頭のクラスはデザイン可能なものである必要があります。ファイル内の先頭のクラスは、IComponent インターフェイスを実装する必要があります。または、Component クラスから派生するか、Component から派生したクラスから派生する必要があります。
コンポーネントの削除後にグリフが残る
カスタム デザイナが Adorner オブジェクトを作成した場合は、デザイナがスコープの外になったときに、デザイン サーフェイスからそれらを削除する必要があります。デザイナの Dispose メソッドで BehaviorServiceAdornerCollection.Remove を呼び出して、Glyph オブジェクトと、関連する Adorner および Behavior オブジェクトを消去します。詳細については、「方法 : デザイン モードでコントロールの外観と動作を拡張する」を参照してください。
既定のデザイナの動作がカスタムの動作によって無効になった
既定のコントロール デザイナによって作成されるグリフは、デザイン サーフェイス上のコントロール全体を対象にします。これは本体グリフと呼ばれます。本体グリフと同じ境界を持つグリフをカスタム コントロール デザイナが作成する場合、本体グリフに関連付けられている基になる Behavior 実装は非表示になります。これにより、スマート タグやグリフのサイズ変更などの既定の機能が表示されるのを防ぐことができます。
Behavior オブジェクト間でメッセージを渡すことはできません。そのため、マウス メッセージを処理して、それを基になる Behavior オブジェクトに転送することはできません。コントロール全体を対象にしたグリフを実装する場合は、カスタム デザインの外観および動作全体に注意する必要があります。
デザイナのイベントが予期しない方法で発生した
カスタム デザイナが ComponentRemoved、ActiveDesignerChanged、および SelectionChanged などのデザイナ イベントにイベント ハンドラをアタッチする場合は、デザイナの Dispose メソッド内のイベント ハンドラをデタッチする必要があります。
これを実行しないと、デザイン時に予期しない動作が発生する可能性があります。発生する可能性のある症状を次の一覧に示します。
エラー メッセージ ボックス : "このコマンドの処理中にエラーが発生しました。"
エラー メッセージ ボックス : "オブジェクト参照がオブジェクト インスタンスに設定されていません。"
コンポーネントが削除されたり、デザイナが閉じられると、イベント ハンドラが不正に呼び出されます。
コレクションをシリアル化できない
カスタム コンポーネントまたはコントロールのコレクション プロパティをシリアル化する場合は、DesignerSerializationVisibilityAttribute を適用し、Content に設定します。詳細については、「方法 : 標準の型のコレクションを DesignerSerializationVisibilityAttribute でシリアル化する」を参照してください。
デザイナが UndoEngine 参照を取得できない
フォームの読み込み中に UndoEngine サービスへの参照を取得しようとすると、GetService メソッドは null を返します。
UndoEngine サービスは、フォームの読み込みが完了するまでは作成および有効化されません。フォームの読み込みが完了すると、それ以降の GetService の呼び出しで UndoEngine 参照が返されます。
通常は、UndoEngine を直接参照する必要が生じることはほとんどありません。直接参照する必要があるのは、通常、ユーザーが操作を行った場合か、デザイナの読み込み後です。
デザイン環境でコンポーネントのプロパティの変更が認識されない
直接プロパティを設定した場合、デザイン環境はコンポーネントまたはコントロールに加えられた変更を認識しません。ComponentChanged などのイベントが発生するためには、PropertyDescriptor.SetValue メソッドを使用してコンポーネントのプロパティの値を設定する必要があります。これにより、デザイン環境にプロパティの変更が通知され、デザイン サーフェイスおよび PropertyGrid コントロールを正しく更新できます。詳細については、「方法 : デザイン モードでコントロールの外観と動作を拡張する」を参照してください。
DesignerAttribute 構文
カスタム デザイナをデザイン元のコントロールにアタッチするには、DesignerAttribute をコントロールに適用します。
DesignerAttribute パラメータを正確に指定する必要があります。指定しない場合、デザイン環境はカスタム デザイナを読み込みません。
コンポーネントまたはデザイナの変更後のデザイン環境の更新
コンポーネントのデザイン時の側面に変更を加える場合は、コンポーネントのプロジェクトをビルドし直す必要があります。加えて、このコンポーネントを使用している別の Windows フォーム プロジェクトが現在開かれている場合は、多くの場合、変更内容を表示するのにプロジェクトを更新する必要があります。通常は、コンポーネントが含まれているデザイン ウィンドウをいったん閉じてから開き直す必要があります。
新しく生成された Windows フォームの FxCop 警告 : DoNotInitializeUnnecessarily
Windows フォーム デザイナは、Windows フォーム アプリケーション プロジェクト用に C# で次のコードを生成します。
private System.ComponentModel.IContainer components = null;
有効な FxCop ルールに基づいて、FxCop は "DoNotInitializeUnnecessarily" 警告を生成します。これは、参照プロパティに関して null が共通言語ランタイム (CLR) の既定であるためです。
デザイナが components フィールドを初期化して null にしない場合、C# コンパイラは次の警告を生成します。
"'Form1.components' は割り当てられません。常に既定値 'null' を使用します。"
SuppressMessageAttribute を使用すると、FxCop 警告が表示されないようにできます。ただし、それにより、クラス名が変更されたときにメンテナンス上の問題が発生する可能性があります。したがって、FxCop 警告を無視することをお勧めします。
部分クラスおよび Windows フォーム デザイナ
既定では、Windows フォーム デザイナは、デザイナのシリアル化コードをコンポーネントのメイン ファイルとは別の専用のファイルに保存します。たとえば、Windows フォーム アプリケーション プロジェクトで、Form1 クラスの定義は次の表に示すように 2 つのファイルに分割されます。
ファイル (C# のファイル名) |
機能 |
---|---|
Form1.cs |
メイン クラス ファイル |
Form1.Designer.cs |
デザイナが出力するコード |
ファイル (VB のファイル名) |
機能 |
---|---|
Form1.vb |
メイン クラス ファイル |
Form1.Designer.vb |
デザイナが出力するコード |
一般に、Windows フォーム デザイナが生成するコードを変更する必要はありません。代わりにメイン クラスのファイルを編集します。
Windows フォーム デザイナは、partial キーワードを使用して、Form1 の実装を 2 つのファイルに分割します。これにより、デザイナが出力したコードがコードに混入することを防ぐことができます。partial キーワードの詳細については、「部分クラスと部分メソッド (C# プログラミング ガイド)」および「Partial (Visual Basic)」を参照してください。
Windows フォーム デザイナでは、デザイン可能な型の定義を 2 つ以上の partial 実装に分割することはサポートされていません。この制限には、型の 3 番目の部分定義を含むクラス ファイルの新規作成や、メイン ファイルまたはデザイナ ファイルに対する型の 3 番目の部分クラスの定義の追加が含まれます。この方法で定義されたメンバは、Windows フォーム デザイナでは表示されません。
レガシ カスタム コントロールが原因でデザイナで予期しない動作が発生する
デザイナで型が無効化されると、ComponentSerializationService が一部の再読み込みを実行して、更新された型でデザイナを更新します。Visual Studio 2005 より前のバージョンの Visual Studio では、デザイナが完全に再読み込みされていました。Visual Studio 2005 での一部の再読み込み動作は完全な再読み込みよりも処理時間が短く、"元に戻す" スタックも保持されます。
Visual Studio 2005 より前に作成されたコンポーネントおよび対応するシリアライザは、一部の再読み込みに対応できない場合があります。完全な再読み込みの実行中にのみ逆シリアル化するように作成されたコンポーネントとコントロールが原因で、予期しない動作が発生する可能性があります。レガシ コントロールが存在する場合に Windows フォーム デザイナで見られる兆候には、スタック オーバーフロー、ハング、または空白領域があります。
devenv.exe.config ファイルに次の設定を追加すると、完全な再読み込み動作に戻すことができます。Visual Studio 2005 を既定の場所にインストールした場合、このファイルは C:\Program Files\Microsoft Visual Studio 8\Common7\IDE フォルダにあります。
<appSettings>
<add key="EnableOptimizedDesignerReloading" value="false" />
</appSettings>
ホストされているデザイナのスマート タグによって例外が発生する
Visual Studio の外部でデザイナをホストしている場合は、スマート タグによって NullReferenceException が発生することがあります。この問題を解消するには、デザイナに IUIService 参照を追加し、Styles プロパティを実装します。Styles によって公開される IDictionary で、次のコードに示すように新しい Font を "DialogFont" キーで指定される要素として割り当てます。
Styles["DialogFont"] = new Font(...);
コンポーネント アイコンがツールボックスに表示されない
Visual Studio で、ToolboxBitmapAttribute を使用してアイコンをカスタム コンポーネントに関連付けても、自動的に生成されたコンポーネントのビットマップがツールボックスに表示されません。ビットマップを表示するには、[ツールボックス アイテムの選択] ダイアログ ボックスを使用してコントロールを再読み込みします。