none
Contagem de linhas no RichTextBox RRS feed

  • Pergunta

  • Olá Galera! Problema antigo... como determinar a quantidade de linhas digitadas em um RichTextBox? Em VB, o Andre Alves de Lima, lá em dezembro de 2010, apresentou uma solução aqui neste fórum, empregando o que creio ser uma propriedade do VB. No entanto, não encontrei nada parecido no C#. Na verdade, o que preciso é limitar o número de linhas físicas do texto exibido a fim de caber em uma folha impressa. Alguém aí poderia me dar uma luz?

    Obrigado.

    Edson Oliveira

    domingo, 12 de novembro de 2017 13:20

Respostas

Todas as Respostas

  • Bom dia,

    Refiz o exemplo do André para C#. Basicamente, defini um controle personalizado, um ExtendedRichTextBox com uma propriedade chamada MaxLineNumber que define o número máximo de linhas que você pode digitar:

    using System;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WnForms_Code_Tester
    {
        public class ExtendedRichTextBox : RichTextBox
        {
            private uint _MaxLineNumber;
            [System.ComponentModel.Browsable(true)]
            public uint MaxLineNumber
            {
                get
                {
                    return _MaxLineNumber;
                }
                set
                {
                    _MaxLineNumber = value;
                }
            }
    
            protected override void OnKeyDown(KeyEventArgs e)
            {
                if (MaxLineNumber == 0) goto basepoint;
                long l = CountLines(this.Text);
                if (l == MaxLineNumber - 1)
                    e.Handled = true;
                basepoint:
                base.OnKeyDown(e);
            }
    
            private long CountLines(string text)
            {
                return text.LongCount(x => x == '\n');
            }
        }
    }

    Basta criar uma classe no seu programa, colar o código, alterar o namespace, compilar e adicionar nos seus forms...

    Espero ter ajudado.

    Link para o post mencionado em Visual Basic .NET:

    Quantidade de linhas em um RichTextBox


    Herbert Lausmann

    domingo, 12 de novembro de 2017 14:48
  • Aproveitando, vou anexar um código mais complexo que também impede que o usuário cole no RichTextBox um texto maior que o permitido:

    using System;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WnForms_Code_Tester
    {
        public class ExtendedRichTextBox : RichTextBox
        {
            public ExtendedRichTextBox()
            {
                WordWrap = false;
            }
            private uint _MaxLineNumber;
            [System.ComponentModel.Browsable(true)]
            public uint MaxLineNumber
            {
                get
                {
                    return _MaxLineNumber;
                }
                set
                {
                    _MaxLineNumber = value;
                }
            }
    
            protected override void OnKeyDown(KeyEventArgs e)
            {
                if (MaxLineNumber == 0) goto basepoint;
    
                bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V;
                bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert;
    
                if (ctrlV || shiftIns)
                {
                    e.Handled = !CanPaste();
                    goto basepoint;
                }
    
                if (e.KeyCode != Keys.Enter) goto basepoint;
    
                long l = CountLines(this.Text);
                if (l == MaxLineNumber - 1)
                    e.Handled = true;
    
                basepoint:
                base.OnKeyDown(e);
            }
    
            private long CountLines(string text)
            {
                return text.LongCount(x => x == '\n');
            }
    
            private bool CanPaste()
            {
                if (MaxLineNumber == 0) return true;
                if (SelectionLength == TextLength)
                {
                    if (CountLines(Clipboard.GetText(TextDataFormat.UnicodeText)) > MaxLineNumber)
                        return false;
                }
                else
                {
                    if (SelectionLength == 0)
                    {
                        string preview = Text + Clipboard.GetText(TextDataFormat.UnicodeText);
                        if (CountLines(preview) > MaxLineNumber) return false;
                    }
                    else
                    {
                        string preview = Text.Replace(SelectedText, Clipboard.GetText(TextDataFormat.UnicodeText));
                        if (CountLines(preview) >= MaxLineNumber) return false;
                    }
                }
                return true;
            }
        }
    }
    

    O único inconveniente desse código é que para ele funcionar corretamente, a propriedade WordWrap deve ser definida para false.


    Herbert Lausmann

    • Sugerido como Resposta Antero Marques domingo, 12 de novembro de 2017 22:01
    domingo, 12 de novembro de 2017 15:28
  • Obrigado pela resposta Herbert. No entanto, a sua solução não atingiu o esperado pois ela limita ao número de linhas limitadas pelo "\n" que é o mesmo resultado dado pela propriedade "Lines" do controle RichTextBox.

    Explicando melhor, nos casos em que um parágrafo, com a propriedade "WordWrap = true", ocupe três linhas no controle RichTextBox exibido no form, a propriedade "Lines" vai dar como resultado "1" pois há somente um "\n" no texto. No entanto ela ocupa 3 linhas no form que representa o exato tamanho de uma folha.

    O que se precisa é que houvesse uma propriedade que retornasse 3 como o numero de linhas do controle! Ou seja, precisamos que sejam contadas as linhas quebradas juntamente com as linhas encerradas com "\n".

    Mais uma vez, obrigado pelo post, mas o problema continua!

     
    terça-feira, 14 de novembro de 2017 23:46
  • Boa tarde, projesis.

    Conseguiu o que precisava? Se ainda não, o que falta?

    Atenciosamente,

    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    quinta-feira, 16 de novembro de 2017 19:19
    Moderador
  • Oi Felipe.

    O problema ainda continua. A solução indicada pelo Herbert não atingiu o objetivo já que ela é similar ao resultado apresentado pela propriedade Lines do RichTextBox. O que preciso é um contador de linhas mostradas no form exatamente como são vistas no controle, já que o RichTextBox tem o exato tamanho de uma folha impressa e linhas quebradas (WordWrap = true) devem ser contadas não como uma terminada em "\n", mas como número de quebras que ela tiver, de forma a não ocuparem uma nova página impressa.

    Por exemplo, se o parágrafo acima estivesse num RichTextBox Control com WordWrap = true, a propriedade Lines.Count() seria 1 porque para o controle temos 1 linha, no entanto ela está distribuída ou desenhada em 5 linhas. Este seria o resultado esperado (5 linhas). 

    Estou tentando outras possibilidades, mas até agora sem sucesso!

    domingo, 19 de novembro de 2017 00:32
  • Olá Edson!

    Veja se esta resposta nesta thread do StackOverflow te ajuda em algo:

    Measure String inside RichTextBox Control

    Abraço!


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima

    • Marcado como Resposta projesis sábado, 25 de novembro de 2017 16:18
    segunda-feira, 20 de novembro de 2017 07:51
    Moderador
  • Oi André.

    Não era bem isso que eu queria.  O ideal era contar o numero de linhas, mas deu para quebrar o galho. Com este método (Measure String inside RichTextBox Control) deu para ter uma ideia da altura aproximada do texto e com isso saber se cabe na folha impressa.

    Muito obrigado a todos que postaram!

    • Marcado como Resposta projesis sábado, 25 de novembro de 2017 16:24
    sábado, 25 de novembro de 2017 16:24