Frage

Ich habe ein Textfeld in einer Windows Forms -Anwendung erstellt, die mit einer Höhe für den Eingeben von Text in eine einzelne Zeile beginnt. Aber ich möchte, dass das Textfeld seine Höhe automatisch erhöht, wenn der Benutzer in einen in das Steuerelement eingewickelten Text eingeht.

Derzeit habe ich für dieses Textfeld die Eigenschaften Multiline und WordWrap auf wahr eingestellt. Ich habe versucht, das textchangedierte Ereignis zu verwenden, um festzustellen, wann der Text verpackt wurde, aber ich kann keine Eigenschaft finden, die mir dabei hilft. Die Eigenschaft von Linien liefert keine Hilfe mit verpacktem Text. Nur für Text, den der Benutzer eingereicht hat, um eine neue Zeile zu beginnen.

Wie kann ich meine Textbox jedes Mal, wenn sich der Text über die Breite des Textfelds hinaus wickelt, die Höhe erweitern?

War es hilfreich?

Lösung

Die gleiche Art von Idee, wie andere veröffentlicht haben, geben Sie dies in Ihr Textchangereignis ein:

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

Sie benötigen eine Art Mindesthöhe und können möglicherweise einige Polster angeben, aber dies funktioniert.

Andere Tipps

Wenn Sie stattdessen bereit sind, eine Richtextbox zu verwenden (was meiner Erfahrung nach eine Art mürrischer Kontrolle ist, die mit vielen Macken enthält), können Sie das Contents -Event verwenden, das Ihnen die neue erforderliche Größe gibt:

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

Ich habe dies gerade für eine Etikettenkontrolle für ein anderes Projekt geschrieben. Ich habe den Code aus dem Codeprojekt irgendwo abgeholt, denke ich. Das Ändern in ein Textfeld sollte so einfach sein wie das Ändern der Basis.

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

Adamsanes Beitrag war hilfreich, aber das Textfeld wuchs nicht. Ich würde einige Änderungen vornehmen. Meine Mods sind unten:

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

Ich benutze den folgenden Code mit Erfolg bis etwa der 10. Zeile, dann erhält er 1 Charakter aus, aber das funktioniert für mich. Fragen Sie mich nicht nach zufälligen Zahlen wie - 7 und - 12, sie haben etwas mit Polsterung zu tun

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

Leider kann ich keine Einzelheiten bereitstellen, aber Sie müssen wahrscheinlich eine benutzerdefinierte Implementierung durchführen.

Ich würde einen neuen Textfeldtyp - EXDABLETEXTBOX - abgeben und dann müssen Sie ihn von Hand implementieren.

Dies scheint auch relevant für das, was Sie suchen: http://social.msdn.microsoft.com/forums/en-us/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top