トップ回答者
SplitContainerを継承したユーザーコントロールが利用できない

質問
-
DoubleBuffer処理のため、SplitContainerを継承したユーザーフォームを作成しています。
Public Class Workspace Inherits SplitContainer Public Sub New() Me.DoubleBuffered = True End Sub End Class
上記のクラスを作成しリビルド後、デザイナでフォームに貼り付けようとすると、
"ツールボックスアイテム'Workspace'の読み込みに失敗しました。アイテムはツールボックスから削除されます。"と表示されます。なお継承先をPanelとした場合、正常に使うことはできるのですが、どうやら作成の順番で他のユーザーコントロールも使用できなくなる現象が発生するようです。
1.Panelの継承クラス→正常に使える
2.SplitContainerの継承クラス→上記エラー
3.1のクラスを配置しようとする→上記同様エラー
調べたところ、対象のCPUにx64を設定する場合、ユーザーコントロールが使えず同様の現象が発生する報告を見つけたのですが、現状全てのプロジェクトでAnyCPUを設定しており、意図的に設定を変更しておりません。
SplitContainerを継承する場合、何か追記すべき点などあるでしょうか。
開発環境
VisualStudio Community 2015
VB.NET
WindowsFormプロジェクト
回答
-
そもそもの話になってしまうのですが、SplitContainer自体はPanel1,2に外部からアクセスできますが、継承するとアクセスできなくなるのでしょうか?
初歩的な質問ばかり大変申し訳ありません…プロパティは参照できるようですが、Handles キーワードで認識できなくなるみたいですね。
(VB.NET 使いではないので細かい仕様は存じませんが…)DesignerSerializationVisibility 属性で Content がそのクラスのレベルで見えないと探してくれないようなので、無理矢理書くなら以下のように既存プロパティを隠蔽しつつ、属性を指定することでしょうか。
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> Public Overloads ReadOnly Property Panel1 As Panel Get Return MyBase.Panel1 End Get End Property
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年5月23日 0:41
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年6月7日 2:16
すべての返信
-
回答ではないですが、私の環境 (Windows 10 x64 & Visual Studio 2015 Community) で同様の操作を行ってみましたが、再現できませんでした。デザイナーで正しく Workspace を貼り付けることが出来ました。全コードは下記のようにして、プラットフォームを「Any CPU」にしています。
Public Class Form1 End Class Public Class Workspace Inherits SplitContainer Public Sub New() Me.DoubleBuffered = True End Sub End Class
コードや構成を変更した際に、ソリューションのクリーンを行うことで現象は変わりませんでしょうか?
ただ、SplitContainer は デフォルトで DoubleBuffered が True のようですので、この設定のためだけでしたら、継承の必要はないようです。
参考サイト: http://dobon.net/vb/dotnet/control/doublebuffered.html
-
検証ありがとうございます。doublebufferedがデフォルトでtrueなのは初耳でした…勉強になります。
確かに上記コードの場合、問題なく使用できました。
自分の場合、worckbenchクラスをform1クラスとは別に用意したのですが、その場合だと再現されるようです。※追記
新しくプロジェクトを作成すると、問題なく生成できました…
どうも既存の何かしらと競合してる可能性があるので軽く聞き流してもらえればと思います※追記の追記
新規プロジェクトで、新しいクラスでWorkbenchクラスを作ると動作しません。
新規プロジェクトのFormクラスと同じページ内に、新しいWorckbenchクラスを作成すると動作、
その後、新しいクラスを用意し、Workbench2(内容は同じ)を作成すると動作します。
別のクラスを最初に作ってしまうと動作しないようです。- 編集済み no title 2017年5月21日 12:15
-
恥ずかしながら、自らを参照する、と言うのはどういう状態のことを指すのでしょうか…?
基本的には新規プロジェクトを作成し最初にクラスを作る、という作業を行っておりますので、参照を変更する作業などは行っておりません…プロジェクトの参照設定を見て、そのプロジェクトと同じ名前がいれば、自分で自分を参照する状態ですので Delete キーで削っておいてください。
自分で参照設定を操作しなくても、ツールボックスからコントロールを配置した際に誤って追加されることがあります。もっとも、これが原因だとは言い切れません。
ほかの原因があるかもしれないので、参考程度に…。
- 編集済み AzuleanMVP, Moderator 2017年5月21日 14:02
-
追加となりますが、splitcontainerを継承した場合、paintイベントが発生しません。
既存のコントロールの場合、SplitContainer.Panel1.Paintをハンドルさせることで、Panel1内のペイントイベントを拾えていたのですが、ユーザーコントロールの場合、SplitContainer.Panel1.Paintのような書き方ができません…発生しないのか、書けないのか、どちらですか?
また、継承と書かれていたり、ユーザーコントロールと書かれていたり、フォームと書かれていたり、混乱を招く用法が見受けられます。ユーザーコントロールやフォームは、既存コントロールの継承とは違うものを指すことが多いのでご留意ください。継承であればそのまま書けるような気がします。
ユーザーコントロールに貼り付けている SplitContainer 内の Panel1 をユーザーコントロールの外から参照したいのであれば、Panel1 を公開するプロパティを自分で作ってください。(その方法は、プロパティ追加の方法を調べましょう) -
Private Sub SplitContainer1_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Panel1.Paint End Sub
Private Sub Workbench1_Paint(sender As Object, e As PaintEventArgs) Handles Workbench1.Panel1.Paint End Sub
言葉が下手で申し訳ないです…
通常のコントロールの場合、前者の用にPanel1と書いてペイントイベントを拾うことができるのですが、
自分が作成したクラスの場合、後者のように書くことができず、ペイントイベントを拾うことができません。なおPanelを公開するとのことですが、
Public Property MainPanel As Panel Get Return Me.Panel1 End Get Set(value As Panel) End Set End Property
このような形でパネルコントロールを公開し、上記後者のPanel1の部分をMainPanelと書き換えましたが、エラー(BC31412)が出る状態です…
そもそもの話になってしまうのですが、SplitContainer自体はPanel1,2に外部からアクセスできますが、継承するとアクセスできなくなるのでしょうか?
初歩的な質問ばかり大変申し訳ありません… -
そもそもの話になってしまうのですが、SplitContainer自体はPanel1,2に外部からアクセスできますが、継承するとアクセスできなくなるのでしょうか?
初歩的な質問ばかり大変申し訳ありません…プロパティは参照できるようですが、Handles キーワードで認識できなくなるみたいですね。
(VB.NET 使いではないので細かい仕様は存じませんが…)DesignerSerializationVisibility 属性で Content がそのクラスのレベルで見えないと探してくれないようなので、無理矢理書くなら以下のように既存プロパティを隠蔽しつつ、属性を指定することでしょうか。
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> Public Overloads ReadOnly Property Panel1 As Panel Get Return MyBase.Panel1 End Get End Property
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年5月23日 0:41
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年6月7日 2:16