标签在UserControl (Winforms)不显示

本文关键字:显示 Winforms UserControl 标签 | 更新日期: 2023-09-27 18:15:56

有一个带有标签的UserControl,一个自制的"TextBox"(直接继承自Control)和一个按钮。我们的目标是将标签"粘"到相关控件上,这样表单的设计就更直接了。我覆盖了OnPaint()事件,所以"TextBox"的宽度是根据标签的宽度计算的。它的文本取自UserControl的可设计属性。这样,在设计器中就可以看到UserControl的全宽度。所有计算都正确完成(当标签的文本较大时,文本宽度较小,反之亦然……)。还有:如果标签文本为空,则标签被标记为不可见,等等。但是标签没有显示出来。一些想法?TIA

标签在UserControl (Winforms)不显示

我听从了壳牌的建议。但有一个转折。如果你尝试从UserControl OnPaint事件中调用DrawString(),什么也不会发生,因为表单的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 );
    }

最后,UserControl

中的代码
    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;
        }

唯一的缺点是,当在设计器中,TopLevelControl不是IKindForm,所以你不能看到"label"

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

例如

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