简体   繁体   English

组合多个控件的控件子类

[英]sub-class of Control that combines multiple Controls

I'm trying to extend TextBox to add a Label to the left of it and treat it as one Control so I don't have to keep track of both of their sizes, locations, etc. 我正在尝试扩展TextBox,在其左侧添加一个Label并将其视为一个控件,因此不必跟踪它们的大小,位置等。

I've created a TextBoxWithLabel class that extends Control and has TextBox and Label fields, but I'm not really sure what to do for onPaint() - do I have to tell it to manually draw both items? 我创建了一个TextBoxWithLabel类,该类扩展了Control并具有TextBox和Label字段,但是我不确定如何对onPaint()进行操作-我必须告诉它手动绘制两个项目吗? If so, how? 如果是这样,怎么办? I'm guessing the default inherited behaviour doesn't go so far as 'check if I contain any child Controls and if I do, draw them'... 我猜测默认的继承行为不会达到“检查是否包含任何子控件,如果包含子控件,则绘制它们”的程度。

Is this even the best way to do it? 这甚至是最好的方法吗? I previously had my class extend TextBox and just added the Label field, but of course that didn't get added to the Panel containing the TextBoxWithLabel and so wasn't drawn. 我以前有我的类扩展TextBox并仅添加了Label字段,但是当然没有将其添加到包含TextBoxWithLabel的面板中,因此未绘制。

Any suggestions or pokes in the right direction appreciated. 任何建议或朝正确方向的建议都值得赞赏。

Thanks, 谢谢,

Alex 亚历克斯

The typical approach here is a UserControl in which you put both the label and the text box. 这里的典型方法是UserControl,在其中放置标签和文本框。 It is painful though, you have to add a lot of the properties and events of the text box to the user control so it at least resembles a text box. 但是,这很痛苦,您必须将许多文本框的属性和事件添加到用户控件中,以便它至少类似于文本框。 Ugly boilerplate code. 丑陋的样板代码。

Another way to do it is to make a custom text box that sneaks in a label control on the parent. 另一种方法是制作一个自定义文本框,使其潜入父级的标签控件中。 That completely behaves like a TextBox without having to do any work. 这完全像一个TextBox,而无需做任何工作。 Add a new class to your project and paste the code shown below. 将新类添加到您的项目中,然后粘贴以下代码。 Compile. 编译。 Drop the new control from the top of the toolbox onto your form. 将新控件从工具箱的顶部拖放到窗体上。 Set the Description property to the text you want to see appear in the label. 将“描述”属性设置为要显示在标签中的文本。

using System;
using System.Drawing;
using System.Windows.Forms;

class MyTextBox : TextBox {
    private Label label;
    public MyTextBox() {
        label = new Label();
        label.AutoSize = true;
        label.Font = this.Font;
        label.Location = this.Location;
        label.Resize += new EventHandler(label_Resize);
    }
    protected override void OnParentChanged(EventArgs e) {
        // Keeps label on the same parent as the text box
        base.OnParentChanged(e);
        label.Parent = this.Parent;   // NOTE: no dispose necessary
    }

    private void moveLabel() {
        // Keep label right-aligned to the left of the text box
        label.Location = new Point(this.Left - label.Width - 10, this.Top);
    }
    private void label_Resize(object sender, EventArgs e) {
        moveLabel();
    }
    protected override void OnLocationChanged(EventArgs e) {
        base.OnLocationChanged(e);
        moveLabel();
    }

    public string Description {
        get { return label.Text; }
        set { label.Text = value; }
    }

    public override Font Font {
        get { return base.Font; }
        set { base.Font = label.Font = value; }
    }

}

Did you consider using a UserControl? 您是否考虑过使用UserControl? The benefit of a usercontrol is that you can easily put your label and textbox with correct relative positioning. 用户控件的好处是您可以轻松地将标签和文本框放置在正确的相对位置。

  • Custom Control - An extension to an existing control Custom Control -现有控件的扩展
  • User Control - A composition of multiple existing controls User Control -多个现有控件的组合

Choose your candidate. 选择你的候选人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM