Переизобретая элемент управления Label - PullRequest
5 голосов
/ 28 апреля 2010

Мне нужно заново изобрести / воссоздать Label Control с нуля, чтобы добавить в него свою собственную модность. Да, я знаю, о чем ты думаешь (и если ты об этом не думаешь, разве не так?).

Может ли кто-нибудь указать мне правильное направление?

Спасибо.

Цель воссоздания метки в том, что я хочу получить полный контроль над тем, как она рисуется на экране, и чтобы у меня тоже могли быть обработчики событий KeyDown. Например, пользователь может редактировать содержимое метки так же, как он редактирует содержимое элемента управления TextBox.

Кроме того, я не могу просто использовать элемент управления TextBox, поскольку это потребует почти, если не больше работы, чтобы получить желаемый результат.

Ответы [ 5 ]

5 голосов
/ 28 апреля 2010

Почему бы просто не продлить текущий?

class MyMojoLabel : Label // Kind of thing

3 голосов
/ 28 апреля 2010

Хорошей отправной точкой может быть понимание того, как Microsoft внедрила метку.

Чтобы получить более подробный обзор, вы должны взглянуть с помощью Reflector на класс или отладки исходного кода элемента управления Label.

2 голосов
/ 28 апреля 2010

Создайте класс, который наследуется от 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);
    }
}
2 голосов
/ 28 апреля 2010
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
    }
}

Как насчет этого?

1 голос
/ 28 апреля 2010

Создание собственного элемента управления меткой достаточно просто, вам просто нужно начать с 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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...