I wrote a small control that allows to change from label to text box and vice versa, and everything is fine, the problem is that it cuts when going from label to text box, which is strange because while I was testing it everything worked perfectly.
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;
}
}
}
}
I even tried modifying the size of the text box to be the same as the label.
Setting this.AutoSize = false;
in the constructor doesn't disable the property and the auto sizing remains. The type of the ToolBoxItem
attribute of the Label control (as the CheckBox and the RadioButton) is AutoSizeToolboxItem which enables the AutoSize
property when you drop an instance in the designer. This issue is well explained here.
As the referred answer suggests, you can prevent this behavior by decorating the
class with the [ToolboxItem(typeof(ToolboxItem))]
attribute:
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.ComponentModel;
[ToolboxItem(typeof(ToolboxItem))]
public partial class LabelBox : Label
{
//...
}
Alternatively, override the AutoSize
property to always return false
:
public partial class LabelBox : Label
{
[Browsable(false),
Bindable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
EditorBrowsable(EditorBrowsableState.Never)]
public override bool AutoSize => false;
}
Implemented here for the CheckBox control thanks to the comments.
Suggestion: You could rewrite your custom control as follows:
[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);
}
}
Side Notes:
InitializeComponent();
method in this context makes no sense.Visible
property Or the Show/Hide
methods but not both to do the same thing.