C# 用户控件(Winforms)中的标签don';不显示

C# 用户控件(Winforms)中的标签don';不显示,c#,winforms,user-controls,C#,Winforms,User Controls,有一个带标签的用户控件、一个自制的“文本框”(直接从控件继承)和一个按钮。 目标是将标签“粘”到相关控件上,因此表单的设计更加直观。 我重写了OnPaint()事件,因此计算“TextBox”的witdh时考虑了标签的宽度。而其文本又取自UserControl的可设计属性。这样,UserControl的整个宽度就是在设计器中看到的宽度。 所有计算都正确完成(当标签的文本较大时,文本宽度较小,反之亦然…)。再次说明:如果标签文本为空,则标签标记为不可见,诸如此类。 但是没有显示标签。 一些想法?

有一个带标签的用户控件、一个自制的“文本框”(直接从控件继承)和一个按钮。 目标是将标签“粘”到相关控件上,因此表单的设计更加直观。 我重写了OnPaint()事件,因此计算“TextBox”的witdh时考虑了标签的宽度。而其文本又取自UserControl的可设计属性。这样,UserControl的整个宽度就是在设计器中看到的宽度。 所有计算都正确完成(当标签的文本较大时,文本宽度较小,反之亦然…)。再次说明:如果标签文本为空,则标签标记为不可见,诸如此类。 但是没有显示标签。 一些想法?
TIA

您不能在textbox继承的用户控件中添加标签。您必须将控件(标签和文本框)分别放置在用户控件上,而不是继承。因此,您可以通过编程设置文本框的大小和位置。您必须创建要在类或命名空间之外处理的所有属性

比如说

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Browsable(true)]
[DefaultValue(string.Empty)]
public override string Text
{
    get {
        return txtBox.Text;
    }
    set {
        txtBox.Text  = value;
    }
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Browsable(true)]
[DefaultValue("My Lable:")]    
public string LabelText
{
    get{
        return lblLabel.Text;
    }
    Set {
        lblLabel.Text = value;
    }
}

我听从了壳牌的建议。但是有一个转折。 如果尝试从UserControl OnPaint事件中提取字符串(),则不会发生任何错误,因为表单的OnPaint在所有控件之后触发,因此它会清除文本。 我采用的方法是在包含UserControl的表单中创建一个方法,并将其设置为接口。下面是一些代码

接口和辅助类

public interface IKindForm
{
    void DisplayText( DisplayText t );
}

public class DisplayText
{
    public string Text { get; protected set; }
    public Font Font { get; protected set; }
    public Brush Brush { get; protected set; }
    public Point Point { get; protected set; }

    public DisplayText( string text, Font font, Color color, int x, int y )
    {
        Text = text;
        Font = font;
        Brush = new SolidBrush( color );
        Point = new Point( x, y );
    }
}
表单中实现接口和重写的OnPaint的方法

    private List<DisplayText> textsToDisplay = new List<DisplayText>();

    public void DisplayText( DisplayText t )
    {
        if (textsToDisplay.Contains( t ))
            return;
        textsToDisplay.Add( t );
        Invalidate();
    }

    protected override void OnPaint( PaintEventArgs e )
    {
        foreach (DisplayText t in textsToDisplay)
            e.Graphics.DrawString( t.Text, t.Font, t.Brush, t.Point );
        base.OnPaint( e );
    }

唯一的缺点是,在designer中,TopLevelControl不是IKindForm控件,因此无法看到“标签”。

是否在父控件中添加了文本框?如果包含自定义控件的代码,这将非常有用。请在调试器中查看它!通常位置是关闭的。我正在记录完整用户控件、“文本框”和标签的位置(在标签的情况下为左和上)值。它们都是一致的。如果我拼写不好,很抱歉:当然,usercontrol有三个单独的控件:Label、我的自制文本框和一个标准按钮。为什么不画一个字符串而不是放置Label控件呢。因此,您可以正确测量字符串并正确定位文本框。。但是仅仅为了显示一个标签,这看起来非常复杂。。!如果您需要大量输入字段及其标签,则不需要。将标签“粘贴”到字段的能力(也可以通过编程更改颜色),因此,可以在设计器中自由移动标签。我参与了一个大型项目,该项目要求(除其他外)输入控件完全由按键管理。这种“扭曲”只是细微的差别。
    bool labelRegistered = false;

    protected override void OnPaint( PaintEventArgs e )
    {

        int textStart = 0;
        SizeF ssize = new SizeF( 0, 0 );

        if (labelText != null && labelText != String.Empty) {
            ssize = e.Graphics.MeasureString( labelText, labelFont );
            textStart = (int)ssize.Width;
        }

       if (ssize.Width > 0) {
            if (this.TopLevelControl is IKindForm) {
                if (!labelRegistered) {
                    int yPos = this.Location.Y + margin + ComboText.Size.Height / 4;
                    int xPos = this.Location.X - ( textStart + labelOffset );
                    ((IKindForm)this.TopLevelControl).DisplayText( new DisplayText(    labelText, LabelFont, labelColor,
                                                                                     xPos, yPos ) );
                }
            }
            labelRegistered = true;
        }