この記事は公開から4年以上経過しています。
WinFormsのフォームデザイナ上でユーザーコントロールをコンテナとして利用するための手順です。
メインの解説はVB.NETを例としていますが、C#も同様に対応が可能です。
※現在プラグインの問題でクラスダイアグラムが表示されていません。
VisualStudioのフォームデザイナから、上図のようなパネル的な役割のユーザーコントロール上にボタンを配置するようなレイアウトを行なうと、意図したコントロールレイヤーとならない事によって描画時のチラツキやタブオーダーの問題が発生する場合があります。
・フォームデザイナでユーザーコントロール上にボタンを配置
フォーム上にユーザーコントロールを配置して、そのユーザーコントロール上にボタンを配置する場合、フォーム内のコントロールレイヤーは並列になります。
graph LR;
Form-->UserControl;
Form-->Button
Private Sub InitializeComponent()
Me.UserControl1 = New UserControl1()
Me.Button1 = New System.Windows.Forms.Button()
Me.SuspendLayout()
'
'UserControl1
'
Me.UserControl1.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.UserControl1.Location = New System.Drawing.Point(78, 77)
Me.UserControl1.Name = "UserControl1"
Me.UserControl1.Size = New System.Drawing.Size(383, 314)
Me.UserControl1.TabIndex = 0
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(232, 223)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 2
Me.Button1.Text = "Button1"
Me.Button1.UseVisualStyleBackColor = True
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(539, 468)
Me.Controls.Add(Me.Button1) ' ←ボタンがフォームに追加される
Me.Controls.Add(Me.UserControl1) ' ←ユーザーコントロールがフォームに追加される
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
・フォームデザイナでパネル(コンテナ)にボタンを配置
一方、フォーム上にパネルコントロールを配置して、そのパネル上にボタンを配置する場合、フォーム内のコントロールレイヤーは直列になります。
graph LR;
Form-->Panel;
Panel-->Button;
Private Sub InitializeComponent()
Me.Panel1 = New System.Windows.Forms.Panel()
Me.Button1 = New System.Windows.Forms.Button()
Me.Panel1.SuspendLayout()
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.Panel1.Controls.Add(Me.Button1)' ←ボタンがパネルに追加される
Me.Panel1.Location = New System.Drawing.Point(78, 85)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(380, 278)
Me.Panel1.TabIndex = 0
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(160, 149)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
Me.Button1.UseVisualStyleBackColor = True
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(539, 468)
Me.Controls.Add(Me.Panel1)' ←パネルがフォームに追加される
Me.Name = "Form1"
Me.Text = "Form1"
Me.Panel1.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
・ユーザーコントロールのコンテナコントロール化方法
パネルと同様にユーザーコントロールをコンテナとして利用したい場合には、ユーザーコントロールにParentControlDesigner属性を設定します。
' VB.NET
Imports System.ComponentModel
Imports System.ComponentModel.Design
<Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", GetType(IDesigner))>
Public Class UserControl1
End Class
// C#
using System.ComponentModel;
using System.ComponentModel.Design;
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public class UserControl1
{
}
コンテナ化したユーザーコントロール上にボタンを配置したときのコントロールレイヤーは以下のとおりです。
graph LR;
Form-->UserControl;
UserControl-->Button;
Private Sub InitializeComponent()
Me.UserControl1 = New UserControl1()
Me.Button1 = New System.Windows.Forms.Button()
Me.UserControl1.SuspendLayout()
Me.SuspendLayout()
'
'UserControl1
'
Me.UserControl1.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.UserControl1.Controls.Add(Me.Button1) ' ←ボタンがユーザーコントロールに追加される
Me.UserControl1.Location = New System.Drawing.Point(78, 77)
Me.UserControl1.Name = "UserControl1"
Me.UserControl1.Size = New System.Drawing.Size(383, 314)
Me.UserControl1.TabIndex = 0
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(155, 144)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 2
Me.Button1.Text = "Button1"
Me.Button1.UseVisualStyleBackColor = True
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(539, 468)
Me.Controls.Add(Me.UserControl1)' ←ユーザーコントロールがフォームに追加される
Me.Name = "Form1"
Me.Text = "Form1"
Me.UserControl1.ResumeLayout(False)
Me.UserControl1.PerformLayout()
Me.ResumeLayout(False)
End Sub
このようにデザイナ属性を設定することで簡単にコンテナコントロール化することが可能です。
但し、フォーム等へ配置したコンテナ化したユーザーコントロール上に別の部品を配置すると、ユーザーコントロールに元々存在するコントロールのAnchorが意図した振る舞いをしない等、コンテナ化の前後の挙動が変わるため注意が必要です。
以上です。