WinFormカスタムコントロール「デザイナモード」について

11830 ワード

最近MSDNでカスタムLabelをWinFormにドラッグする方法を質問する人を見たとき、AutoSizeは自動的にFalseに設定されました.彼が示した方法は
[C#]
class MyLabel : Label
{
public MyLabel()
{
AutoSize = false;
}
}

[VB.NET]
Class MyLabel
Inherits Label
Public Sub New()
AutoSize = False
End Sub
End Class

簡単で、考え方も正しいようです.MyLabelが初期化されると、コンストラクション関数はすぐに実行され、AutoSizeをFalseに設定する必要があります.残念なことに、この方法は手動符号化ダイナミックロードを使用する場合に問題ありません.
[C#]
 private void Form1_Load(object sender, EventArgs e)
{
Controls.Add(new MyLabel());
}

[VB.NET]
Private Sub Form1_Load(sender As Object, e As EventArgs)
Controls.Add(New MyLabel())
End Sub

しかし、ドラッグ・アンド・ドロップ・ロードで問題が発生します.コントロールがWinFormにドラッグ・アンド・ドロップされると、実際にはコントロールを初期化する操作に相当します.このコードはForm_に直接生成されるわけではありません.Loadではなく、すべてのフォーム上の関数とフォーム自身のUI設計を初期化するためのプライベートな関数InitializeComponentに到着しました.また、デフォルトではLabelに対してAutoSize=Trueが生成されます.これにより、Formが起動すると、AutoSize=Trueを設定し、Falseに設定します.InitializeComponent完了コードは次のとおりです.
[C#]
private void InitializeComponent()
{
this.myLabel1 = new WinFormCSharp.MyLabel();
this.SuspendLayout();
//
// myLabel1
//
this.myLabel1.AutoSize=true;
this.myLabel1.Location = new System.Drawing.Point(108, 160);
this.myLabel1.Name = "myLabel1";
this.myLabel1.Size = new System.Drawing.Size(53, 12);
this.myLabel1.TabIndex = 0;
this.myLabel1.Text = "myLabel1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.myLabel1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}

[VB.NET]
Private Sub InitializeComponent()
Me.myLabel1 = New WinFormCSharp.MyLabel()
Me.SuspendLayout()
'
' myLabel1
'
Me.myLabel1.AutoSize = True
Me.myLabel1.Location = New System.Drawing.Point(108, 160)
Me.myLabel1.Name = "myLabel1"
Me.myLabel1.Size = New System.Drawing.Size(53, 12)
Me.myLabel1.TabIndex = 0
Me.myLabel1.Text = "myLabel1"
'
' Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 12F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(284, 262)
Me.Controls.Add(Me.myLabel1)
Me.Name = "Form1"
Me.Text = "Form1"
AddHandler Me.Load, AddressOf Me.Form1_Load)
Me.ResumeLayout(False)
End Sub

では、どうすればいいのでしょうか.いくつかの方法があります.
一、InitLayoutメソッドを書き換える.このメソッドMSDNには、コンテナにロードされた瞬間(ToolBoxを含む)にWinFormにドラッグされたとき(コンテナに入ったため)が明確に表示されている.このときAutoSizeをFalseに設定すればよいので、参考コードは以下の通りです.
[C#]
class MyLabel : Label
{
protected override void InitLayout()
{
base.InitLayout();
AutoSize = false;
}
}

[VB.NET]
Class MyLabel
Inherits Label
Protected Overrides Sub InitLayout()
MyBase.InitLayout()
AutoSize = False
End Sub
End Class

二、「設計モード」かどうかを判断し、LabelはControlから継承され、Controlには「DesignMode」という属性がある.したがって、AutoSizeを書き換え、設計モードかどうかを判断し(そうでなければ付与を許可し、デフォルトではfalseを返す)、参照コード:
[C#]
class MyLabel : Label
{
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
if (!DesignMode)
{
base.AutoSize = value;
}
}
}
}

[VB.NET]
Class MyLabel
Inherits Label
Public Overrides Property AutoSize() As Boolean
Get
Return MyBase.AutoSize
End Get
Set
If Not DesignMode Then
MyBase.AutoSize = value
End If
End Set
End Property
End Class