【问题标题】:Why is the size of the TextBox cut off?为什么 TextBox 的大小会被截断?
【发布时间】:2020-10-30 04:13:05
【问题描述】:

我写了一个小控件,允许从标签更改为文本框,反之亦然,一切都很好,问题是从标签到文本框时它会中断,这很奇怪,因为当我测试它时一切完美运行。

https://i.imgur.com/yo2tz9O.gif

using System;
using System.Windows.Forms;

namespace LabelBox
{
    public partial class labelbox : Label
    {
        public TextBox textBox = new TextBox();

        public labelbox()
        {
            InitializeComponent();

            textBox.LostFocus += TextBox_LostFocus;
            textBox.KeyDown += TextBox_KeyDown;
            this.Controls.Add(textBox);
            textBox.Hide();
            textBox.Visible = false;
            this.AutoSize = false;
        }

        

        // Sobrescribir el metodo Double Click de la clase Label
        protected override void OnDoubleClick(EventArgs e)
        {
            textBox.Show();
            textBox.Visible = true;
            textBox.Text = this.Text;
            textBox.Focus();
        }

        // Agreagar el metodo Lost Focus del textbox
        protected void TextBox_LostFocus(object sender, EventArgs e)
        {
            this.Text = textBox.Text;
            textBox.Hide();
            textBox.Visible = false;
        }

        // Agregar el metodo Key Down para ENTER del textbox
        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter)
            {
                this.Text = textBox.Text;
                textBox.Hide();
                textBox.Visible = false;
            }
        }                        

    }
}

我什至尝试将文本框的大小修改为与标签相同。

【问题讨论】:

  • 我无法让这段代码真正看到问题所在。但通常,TextBox 需要比标签更多的空间才能正确显示。那么您是否尝试过将标签的尺寸设置得更大?看看这是否正常(高度和宽度,记得禁用自动调整大小)。
  • 拥有一个文本框并将其重新设置为“像一个标签”不是更简单吗?设置只读并删除边框?我相信这是微软在文件属性对话框中所做的,例如路径看起来像一个标签,但可以复制
  • 但是文本框现在看起来是不透明的。

标签: c# textbox user-controls windows-forms-designer


【解决方案1】:

在构造函数中设置this.AutoSize = false; 不会禁用该属性,并且自动调整大小仍然存在。 Label 控件(作为 CheckBox 和 RadioButton)的 ToolBoxItem 属性的类型是 AutoSizeToolboxItem,当您在设计器中放置实例时,它会启用 AutoSize 属性。这个问题很好解释here

正如所引用的答案所暗示的,您可以通过装饰 具有[ToolboxItem(typeof(ToolboxItem))] 属性的类:

using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.ComponentModel;

[ToolboxItem(typeof(ToolboxItem))]
public partial class LabelBox : Label
{
    //...
}

或者,覆盖AutoSize 属性以始终返回false

public partial class LabelBox : Label
{
    [Browsable(false),
        Bindable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        EditorBrowsable(EditorBrowsableState.Never)]
    public override bool AutoSize => false;
}

感谢 cmets,为 CheckBox 控件实现了 here

建议:您可以按如下方式重写您的自定义控件:

[ToolboxItem(typeof(ToolboxItem))]
public class LabelBox : Label
{
    public LabelBox() : base() { }

    // To be able to set the properties of the TextBox in the Properties Window.
    [Browsable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public TextBox TextBox { get; } = new TextBox();

    protected override void OnHandleCreated(EventArgs e)
    {
        if (!Controls.Contains(TextBox))
        {
            TextBox.Leave += (s, a) =>
            {
                Text = TextBox.Text;
                TextBox.Hide();
            };
            TextBox.KeyDown += (s, a) =>
            {
                if (a.KeyCode == Keys.Enter)
                {
                    Text = TextBox.Text;
                    TextBox.Hide();
                    // Optional to prevent the beep...
                    a.SuppressKeyPress = true;
                }
            };
            TextBox.Visible = false;
            TextBox.Dock = DockStyle.Fill;
            Controls.Add(TextBox);
        }

        base.OnHandleCreated(e);
    }

    protected override void OnDoubleClick(EventArgs e)
    {
        TextBox.Show();
        TextBox.Text = Text;
        TextBox.Focus();
    }

    // When you create a disposable object, then you should dispose it.
    protected override void Dispose(bool disposing)
    {
        if (disposing) TextBox.Dispose();
        base.Dispose(disposing);
    }
}

旁注:

  1. 在这种情况下调用InitializeComponent(); 方法没有意义。
  2. 要切换控件的可见性状态,请使用Visible 属性或Show/Hide 方法,但不能同时使用这两种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 2015-02-08
    • 1970-01-01
    • 2012-01-18
    • 2018-03-17
    相关资源
    最近更新 更多