zoukankan      html  css  js  c++  java
  • 关于WinForm自定义控件“设计器模式”

    最近在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中,而是到了一个私有的函数InitializeComponent(一个专门用于初始化全部窗体上函数以及窗体自身UI设计时候的大杂烩)。同时还默认为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
  • 相关阅读:
    Yii的上传类使用CUploadedFile
    后台无刷新修改字段js
    YII CGridView的分析
    YII开发技巧分享——模型(models)中rules自定义验证规则
    easy_ui之窗口弹出的实例
    php后台如何避免用户直接进入方法
    暑假周总结三
    暑假周总结二
    暑假周总结一
    从入门到精通6
  • 原文地址:https://www.cnblogs.com/ServiceboyNew/p/2400580.html
Copyright © 2011-2022 走看看