views:

163

answers:

5

Hi All,

I need to reinvent/recreate the Label Control from scratch to add my own mojoness to it. Yes, I know what you're thinking (and if you're not thinking that, shouldn't you be?).

Can somebody point me in the right direction?

Thank you.

The whole purpose for recreating the label is that I want full control over how it is drawn onto screen, and so that I can have KeyDown Event Handlers for it, too. For example, the user can edit the contents of a label the same way they would edit the contents of a TextBox control.

Also, I cannot just simply use a TextBox control, as it would require almost, if not more work to get my desired result.

+5  A: 

Why not just extend the current one?

class MyMojoLabel : Label // Kind of thing

Kyle Rozendo
I have done this in my current project, mainly to do dynamic language changes and to reduce flickering.
Skizz
His whole point is not to do this from what i understand.class MyMojoLabel : UserControl seems like a better start.
Bastiaan Linders
@Bastiaan Linders - I don't think that a user control would be what the op was talking about. Levels of complexity go from `class MyMojoLabel : Control` to `class MyMojoLabel : Label` to `class MyMojoLabel : UserControl`. A user control is basicaly just a group of existing controls.
Stevo3000
@j-t-s: op is Original Poster. http://www.urbandictionary.com/define.php?term=op
Peter van der Heijden
+2  A: 

A good starting point would maybe to understand how Microsoft implemented the label.

To get a better in-depth look you should take a look with Reflector into the class or debugging the source code of the Label control.

Oliver
+4  A: 
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
    }
}

How about this?

Mike
Looks like we had the same idea at the same time, +1 for the OnKeyDown override (and for using red as the demo color)
Wez
+3  A: 

Create a class that inherits from Control. Use the SetStyle() call to enable user painting and double-buffering, and override the OnPaint(), and any other methods that you need.

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);
    }
}
Wez
+1  A: 

Creating your own label control is simple enough, you just need to start with Control and override OnPaint(). What is going to byte is to turn it into a control that also has focusing behavior. And allows the user to edit the text. By the time you're done, you'll have re-invented the TextBox control. Which is a lot harder than it looks.

Focus on the focusing first, that's the trickiest problem. It isn't very likely that the user will want to focus the control frequently. Maybe some kind of secret handshake, like a double-click. When you detect one, you could create a TextBox control and put it in front of the label. And dispose it when it loses focus, updating the label's Text property. Or a simple context menu that displays a small editing dialog.

An example that uses the double-click to edit approach:

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);
  }
}
Hans Passant
Hmmm interesting... Do you by any change happen to know of any tutorials/Documentation that would put me in the right direction of creating a new Label and/or TextBox Control?
lucifer
@j-t-s: any decent Windows Forms book should help you get started. I updated my post with a sample control that permits editing on a double-click.
Hans Passant