C#创建windows组合控件

一 创建窗体库控件

  1. 创建一个新的Windows Forms Control Library项目,命名为LabelTextbox。
    在这里插入图片描述

  2. 单击设计界面,打开控件的属性。把控件的Name属性改为ctLabelTextbox。
    在这里插入图片描述

  3. 双击工具箱中的标签,把它添加到用户控件中,放在界面的左上角,把它的Name属性改为lblTextBox,把Text属性设置为Label。
    在这里插入图片描述

  4. 双击工具箱中的文本框,把它添加到用户控件中,把它的Name属性改为txtLabelText。
    在这里插入图片描述

二 编写代码 给标签和文本框定位。

需要添加两个属性,Position:允许用户二选一(Right和Below).TextboxMargin,是一个int,表示控件左边界到文本框的像素数。

1. 添加属性:

Position属性,为了让用户可以选择Right和Below,先用这两个值定义一个枚举类型,返回控件项目,添加代码:

        //定义位置选择的两个枚举类型
        public enum PositionEnum
        {
            Right, Below
        }
        //添加Position字段
        private PositionEnum mPosition = PositionEnum.Right;

        //添加Position属性
        public PositionEnum Position
        {
            get { return mPosition; }
            set
            {
                mPosition = value;
                MoveControls();
            }
        }
       

TextboxMargin属性是一样的,但它处理的是一个整数。

        //添加TextboxMargin字段
       private int mTextboxMargin = 0;

        //添加TextboxMargin属性
        public int TextboxMargin
        {
            get { return mTextboxMargin; }
            set
            {
                mTextboxMargin = value;
                MoveControls();
            }
        }

2. 添加事件处理。

在这里插入图片描述
可以看到函数已经添加进来了。
在这里插入图片描述

添加Load函数处理

        //初始化控件和该控件的所有资源
        private void ctLabelTextbox_Load(object sender, EventArgs e)
        {
            lblTextBox.Text = this.Name;//设置label显示的文字
            //设置控件高度
            this.Height = txtLabelText.Height > lblTextBox.Height ? txtLabelText.Height : lblTextBox.Height;
            MoveControls();//移动控件
        }

添加SizeChanged函数处理

//改变控件大小时,重新绘制控件
        private void ctLabelTextbox_SizeChanged(object sender, EventArgs e)
        {
            MoveControls();
        }

//MoveControls函数

        private void MoveControls()
        {
            switch (mPosition)
            {
                case PositionEnum.Below:
                    //设置Textbox的顶部在Label的底部
                    this.txtLabelText.Top = this.lblTextBox.Bottom;
                    this.txtLabelText.Left = this.lblTextBox.Left;

                    //修改Textbox的宽度与控件宽度一致
                    this.txtLabelText.Width = this.Width;

                    this.Height = txtLabelText.Height + lblTextBox.Height;
                    break;
                case PositionEnum.Right:
                    //设置textbox的顶部与label一平
                    txtLabelText.Top = lblTextBox.Top;

                    //如果margin值为零,将textbox与label紧挨着放
                    if (mTextboxMargin == 0)
                    {
                        int width = this.Width - lblTextBox.Width - 3;
                        txtLabelText.Left = lblTextBox.Right + 3;
                        txtLabelText.Width = width;
                    }
                    else
                    {
                        //如果margin值不为零,将textbox 放置在用户定义的位置
                        txtLabelText.Left = mTextboxMargin;
                        txtLabelText.Width = this.Width - mTextboxMargin;
                    }
                    this.Height = txtLabelText.Height > lblTextBox.Height ? txtLabelText.Height : lblTextBox.Height;
                    break;
            }
        }

三 调试用户控件

1. 新建测试项目

从File菜单中选择Add|New Project对话框中创建一个新的Windows Application项目,命名为LabelTextboxTest。在Solution Explorer中,已打开了两个项目。第一个项目是前面创建的LabelTextbox,以黑体字显示。如果要运行解决方案。调试程序就会把该控件用作启动项目,这将会失败,因为控件不是一个独立的项目。为了更正这个问题,右击项目名LabelTextboxTest,选择Set as Startup Project。再运行解决方案,就会运行Windows应用程序项目,且不会报错。
在这里插入图片描述
在这里插入图片描述
右键LabelTextboxTest——设为启动项目
在这里插入图片描述

2. 使用控件

现在,在工具箱的顶部应有一个选项卡LabelTextBox Components。Visual Studio知道在解决方案中有一个Windows Control Library,在其他项目中也可能使用这个库提供控件。所以双击控件ctLabelTextbox,把它添加到窗体中。(如果没有看到LabelTextBox Components,就重新生成一下解决方案就可以看见了)
在这里插入图片描述
在这里插入图片描述
双击ctLabelTextbox,将控件添加到界面中。
在这里插入图片描述

3. 运行项目

在这里插入图片描述
在这里插入图片描述

四 扩展控件功能

到现在为止,还不能对这个控件做什么操作,因为它还不能改变标签和文本框的文本。

1. 添加LabelText和TextboxText两个属性。

private string mLabelText = "";
        public string LabelText
        {
            get
            {
                return mLabelText;
            }
            set
            {
                lblTextBox.Text = value;
            }
        }

        private string mTextboxText = "";
        public string TextboxText
        {
            get
            {
                return mTextboxText;
            }
            set
            {
                mTextboxText = value;
                txtLabelText.Text = mTextboxText;
                MoveControls();
            }
        }

2. 为txtLabelText文本框添加KeyDown KeyPress和KeyUp事件。

在这里插入图片描述

 private void txtLabelText_KeyDown(object sender, KeyEventArgs e)
        {
            OnKeyDown(e);
        }

        private void txtLabelText_KeyPress(object sender, KeyPressEventArgs e)
        {
            OnKeyPress(e);
        }

        private void txtLabelText_KeyUp(object sender, KeyEventArgs e)
        {
            OnKeyUp(e);
        }

3. 添加定制事件处理PositionChanged,当Position属性改变时,引发事件。

(1)创建委托

需要一个合适的委托,用于调用用户赋给事件的方法。委托是由.NET Framework提供的EventHandler委托。

//声明PositionChanged事件,允许用户订阅该事件。
public event System.EventHandler PositionChanged;

(2)赋值事件

用户必须把一个方法赋给事件,以订阅事件。

        //添加Position属性
        public PositionEnum Position
        {
            get { return mPosition; }
            set
            {
                mPosition = value;
                MoveControls();
                if (PositionChanged != null)
                {
                    PositionChanged(this, new EventArgs());
                }
            }
        }

(3)调用用户赋给事件的方法。

 private void ctLabelTextbox1_PositionChanged(object sender, EventArgs e)
        {
            MessageBox.Show("Chnaged");
        }

4. 重新生成解决方案,就可以看见控件的新属性及方法。

在这里插入图片描述
在这里插入图片描述

在LabelTextboxTest窗体上添加一个按钮,双击它,给项目添加按钮Click事件。
在这里插入图片描述

 private void button1_Click(object sender, EventArgs e)
        {
            ctLabelTextbox1.Position = ctLabelTextbox1.Position ==
                LabelTextBox.ctLabelTextbox.PositionEnum.Right ?
                LabelTextBox.ctLabelTextbox.PositionEnum.Below :
                LabelTextBox.ctLabelTextbox.PositionEnum.Right;
        }

5. 运行程序,便可以改变文本框的位置啦。

在这里插入图片描述
点击button1
在这里插入图片描述

五 完整代码

控件完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LabelTextBox
{
    public partial class ctLabelTextbox : UserControl
    {
        //定义位置选择的两个枚举类型
        public enum PositionEnum
        {
            Right, Below
        }
        //添加两个成员字段
        private PositionEnum mPosition = PositionEnum.Right;
        private int mTextboxMargin = 0;

        //声明PositionChanged事件,允许用户订阅该事件。
        public event System.EventHandler PositionChanged;
        //添加Position属性
        public PositionEnum Position
        {
            get { return mPosition; }
            set
            {
                mPosition = value;
                MoveControls();
                if (PositionChanged != null)
                {
                    PositionChanged(this, new EventArgs());
                }
            }
        }
        //添加TextboxMargin属性
        public int TextboxMargin
        {
            get { return mTextboxMargin; }
            set
            {
                mTextboxMargin = value;
                MoveControls();
            }
        }

        private string mLabelText = "";
        public string LabelText
        {
            get
            {
                return mLabelText;
            }
            set
            {
                lblTextBox.Text = value;
            }
        }

        private string mTextboxText = "";
        public string TextboxText
        {
            get
            {
                return mTextboxText;
            }
            set
            {
                mTextboxText = value;
                txtLabelText.Text = mTextboxText;
                MoveControls();
            }
        }

        public ctLabelTextbox()
        {
            InitializeComponent();
        }

        //初始化控件和该控件的所有资源
        private void ctLabelTextbox_Load(object sender, EventArgs e)
        {
            lblTextBox.Text = this.Name;//设置label显示的文字
            //设置控件高度
            this.Height = txtLabelText.Height > lblTextBox.Height ? txtLabelText.Height : lblTextBox.Height;
            MoveControls();//移动控件
        }

        //改变控件大小时,重新绘制控件
        private void ctLabelTextbox_SizeChanged(object sender, EventArgs e)
        {
            MoveControls();
        }

        private void MoveControls()
        {
            switch (mPosition)
            {
                case PositionEnum.Below:
                    //设置Textbox的顶部在Label的底部
                    this.txtLabelText.Top = this.lblTextBox.Bottom;
                    this.txtLabelText.Left = this.lblTextBox.Left;

                    //修改Textbox的宽度与控件宽度一致
                    this.txtLabelText.Width = this.Width;

                    this.Height = txtLabelText.Height + lblTextBox.Height;
                    break;
                case PositionEnum.Right:
                    //设置textbox的顶部与label一平
                    txtLabelText.Top = lblTextBox.Top;

                    //如果margin值为零,将textbox与label紧挨着放
                    if (mTextboxMargin == 0)
                    {
                        int width = this.Width - lblTextBox.Width - 3;
                        txtLabelText.Left = lblTextBox.Right + 3;
                        txtLabelText.Width = width;
                    }
                    else
                    {
                        //如果margin值不为零,将textbox 放置在用户定义的位置
                        txtLabelText.Left = mTextboxMargin;
                        txtLabelText.Width = this.Width - mTextboxMargin;
                    }
                    this.Height = txtLabelText.Height > lblTextBox.Height ? txtLabelText.Height : lblTextBox.Height;
                    break;
            }
        }

        private void txtLabelText_KeyDown(object sender, KeyEventArgs e)
        {
            OnKeyDown(e);
        }

        private void txtLabelText_KeyPress(object sender, KeyPressEventArgs e)
        {
            OnKeyPress(e);
        }

        private void txtLabelText_KeyUp(object sender, KeyEventArgs e)
        {
            OnKeyUp(e);
        }

    }
}

LabelTextboxTest窗体完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LabelTextboxTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void ctLabelTextbox1_PositionChanged(object sender, EventArgs e)
        {
            MessageBox.Show("Chnaged");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ctLabelTextbox1.Position = ctLabelTextbox1.Position ==
                LabelTextBox.ctLabelTextbox.PositionEnum.Right ?
                LabelTextBox.ctLabelTextbox.PositionEnum.Below :
                LabelTextBox.ctLabelTextbox.PositionEnum.Right;
        }
    }
}

六 项目源码

项目源码下载地址

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值