我需要从头开始重新发明/重新创建标签控件,以添加我自己的魔力。是的,我知道你在想什么(如果你不这么想,你不应该吗?)。
有人可以指出我正确的方向吗?
谢谢你。
重新创建标签的全部目的是我希望完全控制它在屏幕上的绘制方式,以便我也可以为它使用 KeyDown 事件处理程序。例如,用户可以像编辑 TextBox 控件的内容一样编辑标签的内容。
此外,我不能只使用 TextBox 控件,因为它几乎需要甚至更多的工作才能获得我想要的结果。
为什么不只是扩展当前的?
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
}
}
这个怎么样?
创建一个继承自 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);
}
}
创建自己的标签控件很简单,只需从 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);
}
}