汎用ユーザーコントロールの埋め込みリソースを修正する
質問
リファクタリング中に、MyControl<T>
です。
埋め込みリソースファイル MyControl`1.resources が見つからないというエラーが実行時に表示されます。 .NET Reflector をざっと見ると、リソースファイルが実際に MyControlと呼ばれていることがわかります。 `1 なしのリソース。
MyControl<T>.InitializeComponent
メソッドの開始時に、おそらく次の行が問題を引き起こしています:
System.ComponentModel.ComponentResourceManager resources =
new System.ComponentModel.ComponentResourceManager(
typeof(MyControl<>));
ComponentResourceManager
に埋め込みリソースファイルMyControl.resources
を使用させるにはどうすればよいですか?この問題を解決する他の方法も歓迎します。
解決
Wimの手法に加えて、ジェネリッククラスと同じ名前の非ジェネリックベースコントロールを宣言し、ジェネリックコントロール/フォームをその非ジェネリックベースクラスから派生させることもできます。
この方法では、デザイナーとコンパイラーの両方をtrickして汎用クラスのリソースファイルを使用させることができ、ベースクラスがセットアップされると、再構築するたびに.designerファイルをいじることなく永続的なデザイナーサポートを取得できます:
// Empty stub class, must be in a different file (added as a new class, not UserControl
// or Form template)
public class MyControl : UserControl
{
}
// Generic class
public class MyControl<T> : MyControl
{
// ...
}
唯一の要件は、ジェネリッククラスとその基本クラスに完全に同じ名前を付けること、および基本クラスが別のクラスファイルに存在する必要があることです。そうでない場合、デザイナーは2つのクラス。
PS。これをフォームでテストしましたが、コントロールでも同じように動作するはずです。
他のヒント
次のようにComponentResourceManager
から継承することで、ロードするリソースファイル名をオーバーライドできることがわかります。
using System;
using System.ComponentModel;
internal class CustomComponentResourceManager : ComponentResourceManager
{
public CustomComponentResourceManager(Type type, string resourceName)
: base(type)
{
this.BaseNameField = resourceName;
}
}
これで、リソースマネージャが次のようにMyControl.resources
をロードすることを確認できます。
System.ComponentModel.ComponentResourceManager resources =
new CustomComponentResourceManager(typeof(MyControl<>), "MyControl");
これは機能しているようです。
編集:デザイナーを使用する場合、上記の行は上書きされます。 生成されたコード領域。デザイナーを避け、バージョン管理ツールを使用して不要な変更を元に戻しますが、ソリューションは理想的ではありません。
Visual <!> nbsp; Studio <!> nbsp; 2008 このエラーがあります:
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MyControl));
ジェネリック型「WindowsFormsApplication1.UserControl1」を使用するには、「1」型の引数が必要です。
私の場合、クラス名の後に括弧なしでコード<>
が生成されたことに注意してください。
おもしろくなってきています。 ImageListが自動生成しない汎用ユーザーコントロールでのコードのコンパイル 。
彼らが言ったこと:
2005年6月7日午後2時49分にMicrosoftが投稿
これは興味深いバグです。 Windows Formsデザイナではサポートされていない一般的なシナリオに遭遇しました。 Whidbey(私のメモ:Visual <!> nbsp; Studio <!> nbsp; 2008?)リリースでは、このサポートを追加できません。これは将来のバージョンで検討します。回避策として、デザイナーを使用して、パブリックTypeプロパティを持つジェネリックなUserControlを作成し、それを継承してTをベースクラスのTypeプロパティに渡すジェネリッククラスを作成できます。
このコントロールはVisual <!> nbsp; Studioフォームデザイナーでも設計できないと思います。
最も簡単で簡単な回避策は、自動生成されたtypeof()
のダミークラスを作成することです。継承したり、外部に公開する必要さえありません:
// Non-generic name so that autogenerated resource loading code is happy
internal sealed class GridEditorForm
{
}
(私の経験では、デザイナーがジェネリックを回避するのに必要な時間は、ジェネリックが提供できる理想的なクールさの価値はありませんでした。ジェネリックのWindowsフォームまたはコントロールを再び使用することはありません。)