【问题标题】:Add label inside textbox control在文本框控件内添加标签
【发布时间】:2014-05-26 17:28:02
【问题描述】:

我想创建一个从 TextBox 继承的控件,它有一个标签,其中“粘贴”到文本框的右侧,并且该文本不是用户可编辑的,而是由属性设置的。如何才能做到这一点?我意识到这个 UX 是一个坏主意的原因可能有很多,但我必须这样做。

【问题讨论】:

  • 是否必须继承自文本框?
  • 嗯...现有代码使用文本框,所以如果我可以从文本框继承,它将是一个简单的替换,无需太多重构。

标签: c# .net winforms textbox label


【解决方案1】:

改编自 Hans Passant 的 Button inside a winforms textbox 答案:

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;
  }
}

结果:

【讨论】:

  • 这很好用!正是我想要的。谢谢。
  • rof。我知道我在哪里搞砸了。试图设置(IntPtr)3(用C#语言)...我忘了把右边距改成2。大声笑:D
  • 有没有办法去除标签和文本框之间的 1 px 边距/填充(白色)??
【解决方案2】:

我会建议你创建一个 UserControlTextBox 和一个 Label 停靠在右边。那应该是更少的痛苦和无错误。

正如您所说,您已经使用TextBox 来避免大量重构,您可以将您在 TextBox 中使用的所有属性添加为“代理属性”。像这样的:

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

这可以帮助您避免大量重构。

【讨论】:

  • 是的,但是我必须将文本框的所有属性复制到用户控件...或重构现有代码...
  • @ian93 有多少属性?这是一次性的工作。您可以添加代理属性,如我在回答中所示。这并不难。
  • 我不认为有一种方法可以在用户控件周围绘制精美的边框,就像文本框上的那样?除了通过 OnPaint 滚动你自己吗?如果是这种情况,那么最好只使用带有成员标签的文本框。
  • @porkchop 从 Textbox 继承并添加控件的方式是什么? TextBox 从未设计为容器控件。它不能很好地工作,例如,如果你输入更多的字符,我猜它会在标签后面。不过不确定。
  • 对不起,当我意识到这是 c# 时,我删除了这篇文章中的代码。不要将 TB 用作容器。相反,将 ref 传递给 TB 构造函数的父控件,即:(ByVal sender As Control),然后只需将标签添加到发件人:sender.Controls.Add(theLabel)。抱歉,又是 VB 代码;p
【解决方案3】:

我实际上会创建一个复合控件,或者只是一个 UserControl,然后将标签和文本框并排放置。然后,您可以移除文本框周围的边框,并用边框包围它们以模仿正常的文本框设计。

最后我会确保用户控件的属性,如Text 映射到文本框,因此很容易将控件用作下拉替换。

【讨论】:

  • 看起来很复杂。您可以在继承的文本框类中创建一个成员标签,并在构造函数中设置它相对于文本框的位置。简单高效。
  • @porkchop 我认为您的想法是正确的...您可以将其扩展为答案吗?
  • 一个边框?那不是css吗? ;o 仍然无法在不使用 OnPaint 的情况下找到在用户控件上制作精美边框的方法...
猜你喜欢
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多