c# تعريف عمودي - كيف أتنقل تلقائيًا إلى أسفل مربع نص متعدد الأسطر؟




6 Answers

على فترات منتظمة ، أقوم بإضافة خطوط نصية جديدة إليه. أرغب في أن يتم تمرير مربع النص تلقائيًا إلى أقصى إدخال في الجزء السفلي (الأحدث) عند إضافة سطر جديد.

إذا كنت تستخدم TextBox.AppendText(string text) ، فسيتم التمرير تلقائيًا إلى نهاية النص الذي تم إلحاقه حديثًا. يتجنب شريط التمرير الخفقان إذا كنت تتصل به في حلقة.

كما يحدث أن يكون ترتيب حجم أسرع من متصلاً خاصية. .Text . على الرغم من أن ذلك قد يعتمد على عدد المرات التي تتصل بها ؛ كنت اختبار مع حلقة ضيقة.

لن يتم التمرير هذا إذا تم استدعاؤه قبل ظهور مربع النص ، أو إذا كان مربع النص غير مرئي (على سبيل المثال ، في علامة تبويب مختلفة في TabPanel). راجع TextBox.AppendText () لا autoscrolling . قد يكون هذا أو لا يكون مهمًا ، اعتمادًا على ما إذا كنت تحتاج إلى autoscroll عندما لا يتمكن المستخدم من رؤية مربع النص.

يبدو أن الطريقة البديلة من الإجابات الأخرى لا تعمل أيضًا في هذه الحالة. طريقة واحدة حوله هي إجراء التمرير إضافية على الحدث VisibleChanged :

textBox.VisibleChanged += (sender, e) =>
{
    if (textBox.Visible)
    {
        textBox.SelectionStart = textBox.TextLength;
        textBox.ScrollToCaret();
    }
};

داخليًا ، يقوم AppendText بشيء مثل هذا:

textBox.Select(textBox.TextLength + 1, 0);
textBox.SelectedText = textToAppend;

ولكن يجب ألا يكون هناك سبب للقيام بذلك يدويا.

(إذا قمت بفكها بنفسك ، سترى أنها تستخدم بعض الأساليب الداخلية الأكثر فعالية ، ولديها ما يبدو أنه حالة خاصة بسيطة).

كتابة الوورد

لدي مربع نص مع تعيين الخاصية .Multiline إلى true. على فترات منتظمة ، أقوم بإضافة خطوط نصية جديدة إليه. أرغب في أن يتم تمرير مربع النص تلقائيًا إلى أقصى إدخال في الجزء السفلي (الأحدث) عند إضافة سطر جديد. كيف أنجز هذا؟




يبدو أن الواجهة تغيرت في .NET 4.0. هناك method التالية التي تحقق كل ما سبق. كما اقترح تومي Engebretsen ، وضعه في معالج الأحداث TextChanged يجعلها تلقائيا.

textBox1.ScrollToEnd();



كنت بحاجة إلى إضافة تحديث:

textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.Refresh();



لقد وجدت اختلاف بسيط لم يتم تناوله في هذا الموضوع.

إذا كنت تفعل كافة المكالمات ScrollToCarat() كجزء من الحدث Load() الخاص ScrollToCarat() الخاص بك ، فهو لا يعمل. لقد قمت للتو بإضافة استدعاء ScrollToCarat() إلى الحدث Activated() للنموذج الخاص بي ، وهو يعمل بشكل جيد.

تصحيح

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

لذا ، إذا كنت تحصر الحدث Activated() في تمرير النص عند تحميل البرنامج ، فيمكنك إلغاء الاشتراك في الحدث داخل معالج الحدث نفسه ، وبالتالي:

Activated -= new System.EventHandler(this.Form1_Activated);

إذا كان لديك أشياء أخرى تحتاج إلى القيام بها في كل مرة يتم فيها تنشيط النموذج الخاص بك ، فيمكنك تعيين bool على true في المرة الأولى التي يتم فيها تشغيل الحدث Activated() ، حتى لا يتم التمرير على عمليات التنشيط اللاحقة ، ولكن لا يزال بإمكانك القيام بالآخر الأشياء التي تحتاج إلى القيام بها.

أيضاً ، إذا كان TextBox الخاص بك على علامة تبويب غير SelectedTab ، لن يكون لـ ScrollToCarat() أي تأثير. لذلك تحتاج على الأقل لجعلها علامة التبويب المحددة أثناء التمرير. يمكنك التفاف الرمز في YourTab.SuspendLayout(); و YourTab.ResumeLayout(false); إقران إذا كان نموذجك يتلألئ عند القيام بذلك.

نهاية التعديل

أتمنى أن يساعدك هذا!




لأي شخص آخر يهبط هنا متوقعًا لرؤية تطبيق webforms ، فأنت تريد استخدام معالج أحداث endRequest الخاص بـ Page Request Manager ( https://.com/a/1388170/1830512 ). إليك ما قمت به في مربع النص الخاص بي في صفحة محتوى من صفحة رئيسية ، يرجى تجاهل حقيقة أنني لم أستخدم متغيرًا لعنصر التحكم:

var prm = Sys.WebForms.PageRequestManager.getInstance();

function EndRequestHandler() {
    if ($get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>') != null) {
        $get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>').scrollTop = 
        $get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>').scrollHeight;
    }
}

prm.add_endRequest(EndRequestHandler);



أنا استخدم وظيفة لهذا:

private void Log (string s) {
    TB1.AppendText(Environment.NewLine + s);
    TB1.ScrollToCaret();
}



Related