重新发明标签控件

我需要从头开始重新创建/重新创建Label Control以添加我自己的mojoness。 是的,我知道你在想什么(如果你不这么想,你不应该这样吗?)。

有人能指出我正确的方向吗?

谢谢。

重新创建标签的全部目的是我想要完全控制它在屏幕上的绘制方式,这样我也可以使用KeyDown事件处理程序。 例如,用户可以像编辑TextBox控件的内容一样编辑标签的内容。

此外,我不能简单地使用TextBox控件,因为它几乎需要,甚至更多的工作来获得我想要的结果。

创建自己的标签控件很简单,只需要从Control开始并覆盖OnPaint()即可。 什么是字节是将它变成一个也具有聚焦行为的控件。 并允许用户编辑文本。 当你完成时,你将重新发明TextBox控件。 这比它看起来要困难得多。

首先关注聚焦,这是最棘手的问题。 用户不太可能想要经常聚焦控件。 也许是某种秘密握手,比如双击。 当您检测到一个时,您可以创建一个TextBox控件并将其放在标签前面。 当它失去焦点时处理它,更新标签的Text属性。 或者是一个显示小编辑对话框的简单上下文菜单。

使用双击编辑方法的示例:

using System; using System.Windows.Forms; class MyLabel : Label { private TextBox mEditor; protected override void OnDoubleClick(EventArgs e) { if (mEditor == null) { mEditor = new TextBox(); mEditor.Location = this.Location; mEditor.Width = this.Width; mEditor.Font = this.Font; mEditor.Text = this.Text; mEditor.SelectionLength = this.Text.Length; mEditor.Leave += new EventHandler(mEditor_Leave); this.Parent.Controls.Add(mEditor); this.Parent.Controls.SetChildIndex(mEditor, 0); mEditor.Focus(); } base.OnDoubleClick(e); } void mEditor_Leave(object sender, EventArgs e) { this.Text = mEditor.Text; mEditor.Dispose(); mEditor = null; } protected override void Dispose(bool disposing) { if (disposing && mEditor != null) mEditor.Dispose(); base.Dispose(disposing); } } 

为什么不扩展当前的?

class MyMojoLabel : Label // Kind of thing

一个好的起点可能是了解Microsoft如何实现标签。

为了更好地深入了解,您应该看一下Reflector到类或调试 Label控件的源代码 。

 public class MyLabel : System.Windows.Forms.Label { protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint(e); // or leave base out // you would determine these values by the length of the text e.Graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Red), 0, 0, 50, 12); } protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e) { base.OnKeyDown(e); // although a label has a KeyDown event I don't know how it would // receive focus, maybe you should create a text box that looks // like a label } } 

这个怎么样?

创建一个inheritance自Control的类。 使用SetStyle()调用来启用用户绘制和双缓冲,并覆盖OnPaint()以及您需要的任何其他方法。

 class MyLabel : System.Windows.Forms.Control { public MyLabel() { this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); } protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint(e); ControlPaint.DrawBorder3D( e.Graphics, this.ClientRectangle, Border3DStyle.Etched, Border3DSide.All); e.Graphics.DrawString(this.Text, this.Font, Brushes.Red, 0, 0); } }