Domanda

Ho creato una casella di testo in un'applicazione Windows Form che inizia ad un'altezza per l'immissione di testo in una sola riga. Ma vorrei che la casella di testo aumentasse automaticamente la sua altezza se l'utente inserisce del testo racchiuso nel controllo.

Attualmente, per questa casella di testo, ho le proprietà multilinea e wordwrap impostate su true. Ho provato a utilizzare l'evento TextChanged per determinare quando è stato eseguito il wrapping del testo ma non riesco a trovare alcuna proprietà che mi possa aiutare in questo. La proprietà Lines non fornisce alcun aiuto con il testo a capo; solo per il testo che l'utente ha premuto invio per iniziare una nuova riga.

Come posso far espandere la mia casella di testo ogni volta che il testo supera la larghezza della casella di testo?

È stato utile?

Soluzione

Stesso tipo di idea che altri hanno pubblicato, inseriscilo nel tuo evento textChanged:

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

Avrai bisogno di un'altezza minima e possibilmente di specificare un po 'di imbottitura, ma questo funziona.

Altri suggerimenti

Se invece sei disposto a utilizzare un RichTextBox (che, secondo la mia esperienza, è una specie di controllo scontroso che viene fornito con molte stranezze), puoi utilizzare l'evento ContentsResized, che ti dà la nuova dimensione richiesta:

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

Ho appena scritto questo per un controllo etichetta per un altro progetto. Ho ottenuto il codice dal progetto di codice da qualche parte penso. Cambiarlo in una casella di testo dovrebbe essere semplice come cambiare 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();
    }
}

Il post di AdamSane è stato utile ma la casella di testo non è cresciuta. Vorrei apportare alcune modifiche. Le mie mod sono qui sotto:

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

Sto usando il codice qui sotto con successo fino all'incirca alla decima riga, quindi viene rimosso 1 carattere, ma questo funziona per me. Non chiedermi dei numeri casuali come - 7 e - 12, hanno qualcosa a che fare con il riempimento

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

Sfortunatamente, non posso fornire dettagli ma probabilmente dovrai fare un'implementazione personalizzata.

Deriverei un nuovo tipo di casella di testo - ExpandableTextBox - e quindi dovrai implementarlo manualmente.

Questo sembra rilevante anche per quello che stai cercando: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top