Pergunta

Eu criei uma caixa de texto em um aplicativo Windows Forms que começa a uma altura para inserir o texto em uma única linha. Mas eu gostaria que a caixa de texto aumentasse automaticamente sua altura se o usuário inserir texto envolto no controle.

Atualmente, para esta caixa de texto, tenho as propriedades multiline e o wordwrap definido como true. Tentei usar o evento TextChanged para determinar quando o texto foi embrulhado, mas não consigo encontrar qualquer propriedade que me ajude com isso. A propriedade das linhas não fornece ajuda com texto embrulhado; Somente para texto que o usuário acertou em Enter para iniciar uma nova linha.

Como posso fazer com que minha caixa de texto expanda sua altura cada vez que o texto passa pela largura da caixa de texto?

Foi útil?

Solução

Mesmo tipo de ideia que os outros postaram, coloque isso em seu evento TEXTCHANGED:

Dim s As SizeF = TextRenderer.MeasureText(txt.Text, txt.Font, txt.ClientRectangle.Size, TextFormatFlags.WordBreak)
txt.Height = CInt(s.Height)

Você precisará de algum tipo de altura mínima e, possivelmente, especificar algum preenchimento, mas isso funciona.

Outras dicas

Se você estiver disposto a usar uma caixa de RichText (que, na minha experiência, é uma espécie de controle mal -humorado que vem com muitas peculiaridades), você pode usar o evento ScentsResized, que fornece o novo tamanho necessário:

private void HandleContentsResized(object sender, ContentsResizedEvenetArgs e)
{
    int newheight = e.NewRectangle.Height;
}

Acabei de escrever isso para um controle de etiqueta para um projeto diferente. Eu tirei o código do projeto de código em algum lugar, eu acho. Alterá -lo para uma caixa de texto deve ser tão simples quanto alterar a base.

public class GrowLabel : Label
{
    private bool _growing;
    //public bool GrowFontSize { get; set; }

    public GrowLabel()
    {
        AutoSize = false;
        //GrowFontSize = false;
    }

    public override sealed bool AutoSize
    {
        get { return base.AutoSize; }
        set { base.AutoSize = value; }
    }

    private void ResizeLabel()
    {
        if (_growing) return;
        try
        {
            _growing = true;

            var sz = new Size(Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.WordBreak);
            Height = sz.Height;
        }
        finally
        {
            _growing = false;
        }
    }

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        ResizeLabel();
    }

    protected override void OnFontChanged(EventArgs e)
    {
        base.OnFontChanged(e);
        ResizeLabel();
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        ResizeLabel();
    }
}

A postagem de Adamsane foi útil, mas a caixa de texto não cresceu. Eu teria para fazer algumas modificações. Meus mods estão abaixo:

class GrowTextBox : TextBox
{
    private double m_growIndex = 0.0;
    private Timer m_timer;

    public GrowTextBox()
    {
        AutoSize = false;
        this.Height = 20;

        // Without the timer, I got a lot of AccessViolationException in the System.Windows.Forms.dll.
        m_timer = new Timer();
        m_timer.Interval = 1;
        m_timer.Enabled = false;
        m_timer.Tick += new EventHandler(m_timer_Tick);

        this.KeyDown += new KeyEventHandler(GrowTextBox_KeyDown);
    }

    void GrowTextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A)
        {
            this.SelectAll();
        }
    }

    void m_timer_Tick(object sender, EventArgs e)
    {
        var sz = new Size(Width, Int32.MaxValue);
        sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.TextBoxControl);

        m_growIndex = (double)(sz.Width / (double)Width);

        if (m_growIndex > 0)
            Multiline = true;
        else
            Multiline = false;

        int tempHeight = (int)(20 * m_growIndex);

        if (tempHeight <= 20)
            Height = 20;
        else
            Height = tempHeight;

        m_timer.Enabled = false;
    }

    public override sealed bool AutoSize
    {
        get { return base.AutoSize; }
        set { base.AutoSize = value; }
    }


    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        m_timer.Enabled = true;
    }

    protected override void OnFontChanged(EventArgs e)
    {
        base.OnFontChanged(e);
        m_timer.Enabled = true;
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        m_timer.Enabled = true;
    }
}

Estou usando o código abaixo com sucesso até a 10ª linha, então ele desligou um caractere, mas isso funciona para mim. Não me pergunte sobre os números aleatórios como - 7 e - 12, eles têm algo a ver com estofamento

    private void txbDescription_TextChanged(object sender, EventArgs e)
    {
        SizeF s = TextRenderer.MeasureText(txbDescription.Text, txbDescription.Font, txbDescription.ClientRectangle.Size, TextFormatFlags.TextBoxControl);

        int lines = (int)Math.Ceiling((decimal)Convert.ToInt32(s.Width - 7) / ((decimal)txbDescription.Width - 12));

        if (lines == 0)
        {
            txbDescription.Height = 20;
        }
        else
        {
            txbDescription.Height = 20 + (lines - 1) * 13;
        }
    }

Infelizmente, não posso fornecer detalhes, mas você provavelmente precisará fazer uma implementação personalizada.

Eu derivaria um novo tipo de caixa de texto - ExpandableTextBox - e você precisará implementá -lo manualmente.

Isso também parece relevante para o que você está procurando: http://social.msdn.microsoft.com/forums/en-us/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top