从今天开始在这边分享本人对UserControl自定义控件的研究,主要针对多个控件组合为一个控件,展示控件显示风格的与众不同,我还没真正成为一位程序员,纯属业余,不过我具备了程序员一样的特点--很懒,写一些小程序供自己使用方便自己的业务,但是为了实现一个功能拖拉了多个控件到窗体中,还要对这些控件进行有序的排版(一个排版非常乱的程序自己用的都不爽),所以我想着如果能编写一个控件,把我要的这些控件都拖拉进去组合成一个控件我要的时候只要拖拉我自定义的这个控件进来就能直接用了,也不用每次都去排版排了半天。好了直接进入主题吧。
这次我用Label和TextBox这两个控件来组合。
一、演示效果图及原理说明
1.控件效果演示
在窗体界面设计的时候拖放到窗体中长的样子,我们来看下运行以后的效果。
这边三个控件呈现的三个不同的显示效果,第一个控件没有字段名,我把字段名清空了,所以就显示成一条下划线了,如果像第二个控件那样的话就是一个十足十的文本框了,第二个控件是有字段名的加上一个文本框,这个时候正处于编辑状态,在里面输入了一些内容,第三个控件我在里面输入了内容了,让他处于浏览状态这样子的话就显示成内容加上下划线的效果了。这些就是本次UserControl组合控件要实现的功能了。
2.实现原理
字段Label控件我用它来显示字段名,值Label控件我用它来显示用户输入的值,当该Label控件显示的时候整个控件处于浏览状态,TextBox控件我用它来输入值,当该控件显示的时候整个控件处于编辑状态,如上图大家看到了在控件处于浏览状态的时候有一条下划线,这条下划线我用画图的方式把它绘制出来,并给控件提供了一个改变该下划线的颜色的属性,有了这些思路这个控件就很容易实现了。
控件的演示及原理说明部分就到这里了,接下来我们开始来实现这些功能。
二、功能实现
1.控件界面设计
效果图:
在这里面我用到了四个控件,两个label控件和一个textbox控件,但是这边看到的明明只有两个控件呀,一个label控件和一个textbox控件,还有第三个控件隐藏在了textbox控件的背后啦,第四个控件是一个timer控件为了解决焦点定位问题加上的。
左边那个Label控件,我们就用label2吧,右边Label控件用label1,textbox就叫textbox1,控件的名字就命名好啦,比较懒了一点没有给这些控件一个好名字,大家可以这么命名:左边的Label控件叫lblFiled,右边的Label控件用lblValue,TextBox控件用txtValue,这样的名字更有意义一点,好吧我们就用有意义的名字来编写吧,养成一个好的代码编写习惯是很重要的。接下来我们把lblValue控件的AutoSize属性设置为False,不让他自动调整大小,还有设置一些lblValue和txtValue的Anchor属性,让他们跟随着UserControl的大小自动适应。控件的设置就到这儿了,接下来的事情就交给代码来完成了。
2.代码实现
这边呢我在犹豫着要不要直接贴代码上来,因为我是业余的水准所以代码写得比较糟糕,大家看着不要觉得碍眼,如果可以帮忙指出加以改进的话,小弟我呢会非常感谢你的。
直接贴代码上来吧,代码如下:
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 UserControlToTxtPlusLblLine { public partial class TxtPlusLblLine : UserControl { private Graphics g; public TxtPlusLblLine() { InitializeComponent(); } private void TxtPlusLblLine_Load(object sender, EventArgs e) { txtValue.Visible = false; lblValue.Visible = true; lblValue.Focus(); timer1.Enabled = true; } private void lblValue_MouseDown(object sender, MouseEventArgs e) { lblValue.Visible = false; txtValue.Visible = true; if (UserSystemPasswordChar) { } else { txtValue.Text = lblValue.Text; } } private void txtValue_Leave(object sender, EventArgs e) { txtValue.Visible = false; lblValue.Visible = true; lblValue.Focus(); if (UserSystemPasswordChar && txtValue.Text != "") { lblValue.Text = "Secret"; } else { lblValue.Text = txtValue.Text; } } public string UText { get { return txtValue.Text; } set { lblValue.Text = value; txtValue.Text = value; } } public override string Text { get { return txtValue.Text; } set { txtValue.Text = value; } } public Boolean ReadOnly { get { return txtValue.ReadOnly; } set { txtValue.ReadOnly = value; } } public Boolean UserSystemPasswordChar { get { return txtValue.UseSystemPasswordChar; } set { txtValue.UseSystemPasswordChar = value; } } /// <summary> /// 重写控件获取焦点属性 /// </summary> public override bool Focused { get { lblValue.Visible = false; txtValue.Visible = true; return txtValue.Focused; } } /// <summary> /// 自定义控件加载ComboBox控件的SelectedIndexChanged事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public delegate void TextChangedHandler(object sender, System.EventArgs e); public event TextChangedHandler UTextChanged; private void txtValue_TextChanged(object sender, EventArgs e) { try { UTextChanged(sender, e); } catch { } } public delegate void DoubleClickHandler(object sender, System.EventArgs e); public event DoubleClickHandler UDoubleClick; private void txtValue_DoubleClick(object sender, EventArgs e) { try { UDoubleClick(sender, e); } catch { } } private Color color = Color.Black; private void TxtPlusLblLine_Paint(object sender, PaintEventArgs e) { g = this.CreateGraphics(); Pen Pen = new Pen(LineColor); if (lblFiled.Text.Trim() != "") { lblFiled.Visible = true; lblValue.Location = new Point(lblFiled.Location.X + lblFiled.Width + 1, 3); lblValue.Width = this.Width - lblFiled.Location.X - lblFiled.Width; txtValue.Location = new Point(lblFiled.Location.X + lblFiled.Width, 0); txtValue.Width = this.Width - lblFiled.Location.X - lblFiled.Width; g.DrawLine(Pen, lblFiled.Location.X + lblFiled.Width, 20, this.Width, 20); } else { lblFiled.Visible = false; lblValue.Location = new Point(1, 3); lblValue.Width = this.Width; txtValue.Location = new Point(0, 0); txtValue.Width = this.Width; g.DrawLine(Pen, 0, 20, this.Width, 20); } } public Color LineColor { get { return color; } set { color = value; } } public string LBLText { get { return lblFiled.Text; } set { lblFiled.Text = value; } } public ContentAlignment LBLTextAlign { get { return lblFiled.TextAlign; } set { lblFiled.TextAlign = value; } } public bool UEnabled { get { return txtValue.Enabled; } set { txtValue.Enabled = value; } } private void timer1_Tick(object sender, EventArgs e) { if (txtValue.Visible) { txtValue.Focus(); } } } }
代码中控件的属性我没有全部定义出来,如果需要可以加入,事件也是一样的,有需要的话就添加进来。
代码中的注释内容比较少嘿嘿,这些还是比较简单的,所以呢看不懂就去研究研究,看得懂的帮我想想看“如果这样做的话可能会更好”以这个话题展开讨论吧,不要看了下就默默的走开了,多少留点东西进来也好呀。
最后原创博文转载请注明出处谢谢http://blog.csdn.net/jsjyyjs07/article/details/18564099