Question

J'ai créé une zone de texte dans une application Windows Forms qui commence à une hauteur permettant de saisir du texte sur une seule ligne. Mais je souhaiterais que la zone de texte augmente automatiquement sa hauteur si l'utilisateur saisit un texte enveloppé dans le contrôle.

Actuellement, pour ce champ de texte, les propriétés multiline et wordwrap sont définies sur true. J'ai essayé d'utiliser l'événement TextChanged pour déterminer quand le texte a été enveloppé, mais je ne parviens pas à trouver une propriété qui puisse m'aider à résoudre ce problème. La propriété Lines ne fournit aucune aide pour le texte enveloppé; uniquement pour le texte que l'utilisateur a tapé sur Entrée pour commencer une nouvelle ligne.

Comment puis-je faire en sorte que ma zone de texte augmente sa hauteur chaque fois que le texte dépasse la largeur de la zone de texte?

Était-ce utile?

La solution

Même type d’idée que d’autres ont posté, mettez ceci dans votre événement textChanged:

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

Vous aurez besoin d'une sorte de hauteur minimale et éventuellement de spécifier un remplissage, mais cela fonctionne.

Autres conseils

Si vous souhaitez utiliser plutôt une RichTextBox (ce qui, d'après mon expérience, est une sorte de contrôle grincheux qui s'accompagne de nombreuses bizarreries), vous pouvez utiliser l'événement ContentsResized, qui vous donne la nouvelle taille requise:

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

Je viens d'écrire ceci pour un contrôle d'étiquette pour un projet différent. J'ai le code du projet de code quelque part je pense. Le changer en une zone de texte devrait être aussi simple que de changer la 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();
    }
}

Le message d'AdamSane a été utile, mais la zone de texte n'a pas augmenté. Je voudrais faire quelques modifications. Mes mods sont ci-dessous:

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;
    }
}

J'utilise avec succès le code ci-dessous jusqu'à la 10ème ligne environ, puis 1 caractère est désactivé, mais cela fonctionne pour moi. Ne me posez pas de questions sur les nombres aléatoires comme - 7 et - 12, ils ont quelque chose à voir avec le remplissage

    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;
        }
    }

Malheureusement, je ne peux pas fournir de détails, mais vous allez probablement avoir besoin d'une implémentation personnalisée.

Je créerais un nouveau type de zone de texte - ExpandableTextBox - et vous devrez ensuite l'implémenter à la main.

Cela semble également pertinent par rapport à ce que vous recherchez: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top