Add label inside textbox control

2019-02-20 18:33发布

I want to make a control which inherits from TextBox and which has a label inside which "sticks" to the right side of the text box and which text is not user-editable but rather is set by a property. How can this be done? I realize there may be many reasons why this UX is a bad idea, but I have to do it this way.

3条回答
在下西门庆
2楼-- · 2019-02-20 18:48

I will suggest you to create a UserControl with TextBox and a Label docked right. That should be pain less and bug free.

As you said you already use TextBox to avoid much refactoring you can add all the properties you used in TextBox as "Proxy properties". Something like this:

class MyTextBox : UserControl
{
    public int TextLength { get { return textbox.TextLength; } }
    ...
}

This can help you to avoid much refactoring.

查看更多
倾城 Initia
3楼-- · 2019-02-20 18:58

I would actually create a composit control, or simply a UserControl, and put a label and textbox next to each other. Then you can remove the borders around the textbox and surround them with a borderbox to mimic the normal textbox design.

Finally I would make sure that the user controls properties, like Text is mapped to the Textbox, so it is easy to use the control as a drop-replacement.

查看更多
来,给爷笑一个
4楼-- · 2019-02-20 19:05

Adapting from Hans Passant's Button inside a winforms textbox answer:

public class TextBoxWithLabel : TextBox {

  [DllImport("user32.dll")]
  private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

  Label label = new Label();

  public TextBoxWithLabel() {
    label.BackColor = Color.LightGray;
    label.Cursor = Cursors.Default;
    label.TextAlign = ContentAlignment.MiddleRight;
    this.Controls.Add(label);
  }

  private int LabelWidth() {
    return TextRenderer.MeasureText(label.Text, label.Font).Width;
  }

  public string LabelText {
    get { return label.Text; }
    set {
      label.Text = value;
      SendMessage(this.Handle, 0xd3, (IntPtr)2, (IntPtr)(LabelWidth() << 16));
      OnResize(EventArgs.Empty);
    }
  }

  protected override void OnResize(EventArgs e) {
    base.OnResize(e);
    int labelWidth = LabelWidth();
    label.Left = this.ClientSize.Width - labelWidth;
    label.Top = (this.ClientSize.Height / 2) - (label.Height / 2);
    label.Width = labelWidth;
    label.Height = this.ClientSize.Height;
  }
}

Result:

enter image description here

查看更多
登录 后发表回答