using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.ComponentModel; namespace JRCookbookControls { [System.Serializable()] public class JRCookbookAutoVerticalGrowTextBox : TextBox { private int _MinCharactersToMultiLine = 0; public JRCookbookAutoVerticalGrowTextBox() { this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); this.TextChanged += JRCookbookAutoVerticalGrowTextBox_TextChanged; this.MultilineChanged += JRCookbookAutoVerticalGrowTextBox_MultilineChanged; this.Resize += JRCookbookAutoVerticalGrowTextBox_Resize; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public int MinCharactersToMultiLine { get { return _MinCharactersToMultiLine; } set { _MinCharactersToMultiLine = value; this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); } } private void JRCookbookAutoVerticalGrowTextBox_Resize(object sender, EventArgs e) { RecalculateTextBoxHeight(); } private void JRCookbookAutoVerticalGrowTextBox_TextChanged(System.Object sender, System.EventArgs e) { this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); RecalculateTextBoxHeight(); } private void JRCookbookAutoVerticalGrowTextBox_MultilineChanged(System.Object sender, System.EventArgs e) { //while we can't hide the multiline property, we can at least enforce its value. this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); } private void RecalculateTextBoxHeight() { // amount of padding to add const int padding = 3; // get number of lines (first line is 0, so add 1) int numLines = this.GetLineFromCharIndex(this.TextLength) + 1; // get border thickness int border = this.Height - this.ClientSize.Height; // set height (height of one line * number of lines + spacing) this.Height = this.Font.Height * numLines + padding + border; } } }