web-dev-qa-db-ja.com

WinFormUserControlのジェネリック基本クラス

WinFormUserControlの汎用基本クラスを作成しました。

public partial class BaseUserControl<T> : UserControl
{
    public virtual void MyMethod<T>() 
    { 
        // some base stuff here 
    }
}

そしてそれに基づくUserControl:

public partial class MyControl : BaseUserControl<SomeClass>
{
    public override void MyMethod<SomeClass>() 
    { 
        // some specific stuff here 
        base.MyMethod<SomeClass>();
    }
}

正常に動作しますが、基本クラスを読み込めないと表示されているため、VisualStudioDesignerでMyControlを編集することはできません。ジェネリックではない別のクラスBaseUserControlを定義しようとしましたが、ロードされることを期待していましたが、うまくいかないようです。

すでに回避策があります。インターフェイスIMyInterface <T>を定義してから、次のようにコントロールを作成します。

public partial class MyControl : UserControl, IMyInterface<SomeClass>

しかし、基本仮想メソッドを失います(大したことではありませんが、それでも...)。

VisualStudio Designerで編集できる、UserControlの基本ジェネリッククラスを作成する方法はありますか?

37
Filini

私たちは同じことをしていて、最初にクラスを専門化し、専門化されたクラスから派生することによって回避します。あなたの例のコードを使用すると、これは次のような意味になります。

public partial class UserControl : UserControlDesignable 
{

...
}
public class UserControlDesignable : BaseUserControl<Someclass> { }

デザイナーはまだ時々不安定な行動をしていますが、ほとんどの場合それは機能します。

35
bernhardrusch

一般的な基本フォームから継承する「通常の」クラスを追加して、デザイナーをだます必要があります。次に、設計可能なフォームはこのクラスから継承する必要があります。したがって、次の2つのクラス定義は同じファイルにあります。ジェネリックベースのユーザーコントロールから継承するクラスがファイルの最後のクラスであることを確認する必要があります。

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

デザイナは、検出したコードファイルの最初のクラスを表示します。

14

これはVisualStudioのバグのようです。

フレームワークを掘り下げることによって(実際には、RootDesignerSerializerから派生したカスタムタイプでCodeDomSerializerを追加し、serializeメソッドをオーバーライドすることによって)、VS CodeDomを証明することができました。プロバイダーは実際にはジェネリッククラスを誤って解析しており、ジェネリッククラスと見なす代わりに、Type.GetType()が見つけることができないclass<T>という名前の通常のクラスと見なしています。

私はまだそれを回避する方法を探していますが、それまでの間、上記の解決策を使用することができます。

Microsoft.Connectのバグレポートがあります。投票してください https://connect.Microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting- from-a-generic-form

3
yoel halb

VisualStudioバージョン> = VS2015.1

VS2015.1から、Windowsフォームデザイナは、一般的な基本クラスを持つクラスを問題なく表示します。したがって、他の投稿にある回避策は、VSの新しいバージョンでは不要になり、次のクラスが問題なくデザイナに表示されます。

public class SomeClassControl:GenericControl<SomeClass>
{
}

古いバージョンのVisual Studio

古いバージョンのVisualStudioの場合は、他の投稿で説明されている回避策を使用してください。

public class SomeClassControl:SomeClassControlBase
{
}
public class SomeClassControlBase:GenericControl<SomeClass>{}
0
Reza Aghaei