سؤال

لقد قمت بإنشاء مربع نص في تطبيق Windows Forms يبدأ على ارتفاع لإدخال النص في سطر واحد. لكنني أرغب في زيادة ارتفاع TextBox تلقائيًا إذا دخل المستخدم نصًا ملفوفًا داخل عنصر التحكم.

حاليًا ، بالنسبة إلى مربع النص ، لدي خصائص Multiline و WordWrap. لقد حاولت استخدام حدث TextChanged لتحديد متى تم لف النص ، لكنني غير قادر على العثور على أي خاصية ستساعدني في ذلك. لا توفر خاصية الخطوط أي مساعدة مع نص ملفوف ؛ فقط للنص الذي ضربه المستخدم Enter لبدء خط جديد.

كيف يمكنني الحصول على مربع النص الخاص بي لتوسيع ارتفاعه في كل مرة يلف فيها النص بعرض مربع النص؟

هل كانت مفيدة؟

المحلول

نفس النوع من الأفكار التي نشرها الآخرون ، وضع هذا في حدث Textchanged:

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

ستحتاج إلى نوع من الحد الأدنى من الارتفاع ، وربما لتحديد بعض الحشو ، ولكن هذا يعمل.

نصائح أخرى

إذا كنت على استعداد لاستخدام RichTextBox بدلاً من ذلك (والتي ، في تجربتي ، هي نوع من التحكم الغاضب الذي يأتي مع الكثير من المراوغات) ، يمكنك استخدام الحدث المحتويات ، والذي يمنحك الحجم الجديد المطلوب:

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

لقد كتبت هذا فقط للتحكم في الملصقات لمشروع مختلف. حصلت على الرمز من مشروع الرمز في مكان ما أعتقد. يجب أن يكون تغييره إلى مربع نص بسيط مثل تغيير القاعدة.

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

كان منشور Adamsane مفيدًا لكن مربع النص لم ينمو. سأقوم بإجراء بعض التعديلات. تعديل بلدي أدناه:

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

أنا أستخدم الكود أدناه مع النجاح حتى حوالي السطر العاشر ، ثم يتم إيقاف تشغيل حرف واحد ، لكن هذا يعمل بالنسبة لي. لا تسألني عن الأرقام العشوائية مثل - 7 و - 12 ، لديهم شيء يتعلق بالحشو

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

لسوء الحظ ، لا يمكنني تقديم تفاصيل ، لكنك ستحتاج إلى تنفيذ مخصص ربما.

سأشتق نوعًا جديدًا من مربع النص - ExploSableTextBox - وبعد ذلك ستحتاج إلى تنفيذه باليد.

هذا يبدو أيضًا ذا صلة بما تبحث عنه: http://social.msdn.microsoft.com/forums/en-us/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top