আমি কীভাবে একটি মাল্টলাইন পাঠ্য বাক্সের নীচে স্বয়ংক্রিয়ভাবে স্ক্রোল করব?


295

আমার কাছে একটি পাঠ্যবাক্স আছে। মাল্টিলাইন সম্পত্তিটি সত্য হিসাবে সেট করা আছে। নিয়মিত বিরতিতে আমি এতে নতুন লাইনের পাঠ্য যুক্ত করছি। আমি চাই যে পাঠ্যবাক্সটি যখনই কোনও নতুন লাইন যুক্ত হবে তখন স্বয়ংক্রিয়ভাবে নীচের সর্বাধিক প্রবেশদ্বারে (সর্বাধিক নতুন) স্ক্রোল করুন। আমি কীভাবে এটি সম্পাদন করব?


6
উত্তরের জন্য এখানে সন্ধান করেছিলেন, এটি খুঁজে পেলেন না, সুতরাং যখন আমি এটি সন্ধান করলাম তখন আমি অনুভব করেছি যে আমি এটি ভবিষ্যতের ব্যবহারকারীদের জন্য এখানে রেখেছি বা যদি অন্য কারওর কাছে আরও ভাল উপায় থাকে।
GWLlosa

2
ভিবিএতে আমার একই জিনিসটি করা দরকার ছিল, যার মধ্যে এই সমস্ত অভিনব প্যান্ট নেই ET ভবিষ্যতের গুগল-ফু-এর জন্য, এখানে জ্বলন রয়েছে: TextBox1.Text = TextBox1. পাঠ্য & "যাই হোক না কেন"; TextBox1.SelStart = Len (TextBox1.Text); TextBox1.SetFocus; ... এবং তারপরে একটি .সেটফোকাসের আগে যা কিছু নিয়ন্ত্রণ ছিল তার ফোকাস back টেক্সটবক্স 1 এ ফোকাস না দিয়ে, এটি যাই করুক না কেন এটি এর স্ক্রোলবারগুলি কখনই আপডেট করবে না।
গর্ডন ব্রুম

1
@ গর্ডনব্রুম হুইল্প, ধন্যবাদ যে আমি এখনই "কোড স্নিপেটস" "" অন্তর্ভুক্তি "বলা শুরু করব। ভাল কাজ. : ডি
সিডনি

উত্তর:


425

নিয়মিত বিরতিতে আমি এতে নতুন লাইনের পাঠ্য যুক্ত করছি। আমি চাই যে পাঠ্যবাক্সটি যখনই কোনও নতুন লাইন যুক্ত হবে তখন স্বয়ংক্রিয়ভাবে নীচের সর্বাধিক প্রবেশদ্বারে (সর্বাধিক নতুন) স্ক্রোল করুন।

আপনি যদি ব্যবহার করেন তবে TextBox.AppendText(string text)এটি স্বয়ংক্রিয়ভাবে নতুন সংযুক্ত পাঠ্যের শেষে স্ক্রোল করবে। যদি আপনি এটিকে কোনও লুপে কল করছেন তবে এটি ঝাঁকুনির স্ক্রোলবার এড়িয়ে চলে।

এটি .Textসম্পত্তির উপর মনোনিবেশ করার চেয়ে দ্রুততর আকারের ক্রম হিসাবেও ঘটে । যদিও এটি নির্ভর করে যে আপনি এটি কতবার কল করছেন; আমি টাইট লুপ দিয়ে টেস্ট করছিলাম।


পাঠ্যবক্সটি দেখানোর আগে ডাকা হলে এটি স্ক্রোল করবে না বা পাঠ্য বাক্সটি অন্যথায় দৃশ্যমান না হলে (যেমন কোনও ট্যাবপ্যানেলের ভিন্ন ট্যাবে)। দেখুন TextBox.AppendText () autoscrolling না । এটি ব্যবহারকারীর পাঠ্যবক্সটি দেখতে না পারলে আপনার অটস্ক্রোলের প্রয়োজন হয় কিনা তার উপর নির্ভর করে এটি গুরুত্বপূর্ণ বা নাও হতে পারে।

দেখে মনে হচ্ছে অন্যান্য উত্তরগুলির বিকল্প পদ্ধতিও এই ক্ষেত্রে কার্যকর হয় না। এর চারপাশের একটি উপায় হল VisibleChangedইভেন্টটিতে অতিরিক্ত স্ক্রোলিং করা :

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

অভ্যন্তরীণভাবে, এর AppendTextমতো কিছু করে:

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

তবে এটি ম্যানুয়ালি করার কোনও কারণ থাকতে হবে না।

(আপনি যদি এটি নিজেই সংশ্লেষ করেন তবে আপনি দেখতে পাবেন এটি সম্ভবত কিছু কার্যকর দক্ষ অভ্যন্তরীণ পদ্ধতি ব্যবহার করে এবং এটি একটি ছোটখাটো বিশেষ ক্ষেত্রে বলে মনে হয়))


7
এই পদ্ধতিটি আরও দ্রুত এবং মসৃণ। স্ক্রোল বারের কোনও 'ঝাঁকুনি' নেই (যা দ্রুত ধারাবাহিকতায় বহু কল করার সময় আরও লক্ষণীয়)।
টালগ্যুই

3
এটি একটি আরও ভাল সমাধান।
জেফ

3
নিজেই এটি তৈরি করার চেষ্টা করছিলাম tb.Text += ....এবং ডাব্লুড্রপপ্রোক এবং মার্শালগুলি এখন আমি বোকা বোধ করছি: ডি
সাইদ ইয়াজদানি

3
টেক্সারিয়ায়ও ফোকাস করা দরকার, প্রথমবার আমি এটি করলাম এটি স্ক্রোল হয়নি কারণ এতে ফোকাস নেই।
Qwerty01

3
অ্যাপেন্ডটেক্সট স্বয়ংক্রিয়ভাবে আমার পঠনযোগ্য পাঠ্যবক্সটি স্ক্রোল করে না, তবে পাঠ্যবক্স যোগ করে Tস্ক্রোলটিওয়েড (); অ্যাপেন্ডটেক্সট কল করার পরে কৌতুকটি হয়েছিল।
ব্র্যান্ডন বার্কলে

143

আপনি নিম্নলিখিত কোড স্নিপেট ব্যবহার করতে পারেন:

myTextBox.SelectionStart = myTextBox.Text.Length;
myTextBox.ScrollToCaret();

যা স্বয়ংক্রিয়ভাবে শেষ পর্যন্ত স্ক্রোল করবে।


5
উত্তরের জন্য এখানে সন্ধান করেছিলেন, এটি খুঁজে পেলেন না, সুতরাং যখন আমি এটি সন্ধান করলাম তখন আমি অনুভব করেছি যে আমি এটি ভবিষ্যতের ব্যবহারকারীদের জন্য এখানে রেখেছি বা যদি অন্য কারওর কাছে আরও ভাল উপায় থাকে।
GWLlosa

4
এই সময়ে এটি সেরা উত্তর হতে পারে তবে এখন আমি মনে করি যে ববের উত্তরটি ওপি'র সমস্যার আরও ভাল সমাধান।
টমসভ

38

দেখে মনে হচ্ছে ইন্টারফেসটি । নেট 4.0 এ পরিবর্তিত হয়েছে । নিম্নলিখিত পদ্ধতিটি যা উপরের সমস্তটি অর্জন করে। টমি এঞ্জাব্রেটসেন পরামর্শ অনুসারে, এটি একটি টেক্সট চেঞ্জড ইভেন্ট হ্যান্ডলারে রাখলে তা স্বয়ংক্রিয় হয়ে যায়।

textBox1.ScrollToEnd();

21
নোট করুন যে পদ্ধতিটি TextBoxBaseক্লাসে System.Windows.Controls.Primitivesনেমস্পেসে রয়েছে ( PresentationFrameworkসমাবেশ, ডাব্লুপিএফ)। এই পদ্ধতি বিদ্যমান এবং WinForms, যার কাজ করবে না নেই TextBoxবর্গ থেকে উত্তরাধিকারী TextBoxBaseমধ্যে System.Windows.Formsনামস্থান ( System.Windows.Formsসমাবেশ, WinForms)।
বব

1
নোট করুন যে ScrollToEnd()অত্যন্ত খারাপ পারফরম্যান্স হতে পারে। আমার অ্যাপ্লিকেশনটিতে এটি প্রোফাইলিং সময়ের 50% এরও বেশি পরিমাণে রয়েছে।
ইরগোহ্যাক

16

টেক্সট চেঞ্জড ইভেন্টে প্রস্তাবিত কোড যুক্ত করার চেষ্টা করুন:

private void textBox1_TextChanged(object sender, EventArgs e)
{
  textBox1.SelectionStart = textBox1.Text.Length;
  textBox1.ScrollToCaret();
}

10
textBox1.Focus()
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();

আমার জন্য কাজ করেনি (উইন্ডোজ 8.1, কারণ যাই হোক না কেন)।
এবং যেহেতু আমি এখনও .NET 2.0 এ থাকি, তাই আমি স্ক্রোলটোইন্ড ব্যবহার করতে পারি না।

তবে এটি কাজ করে:

public class Utils
{
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    private static extern int SendMessage(System.IntPtr hWnd, int wMsg, System.IntPtr wParam, System.IntPtr lParam);

    private const int WM_VSCROLL = 0x115;
    private const int SB_BOTTOM = 7;

    /// <summary>
    /// Scrolls the vertical scroll bar of a multi-line text box to the bottom.
    /// </summary>
    /// <param name="tb">The text box to scroll</param>
    public static void ScrollToBottom(System.Windows.Forms.TextBox tb)
    {
        if(System.Environment.OSVersion.Platform != System.PlatformID.Unix)
             SendMessage(tb.Handle, WM_VSCROLL, new System.IntPtr(SB_BOTTOM), System.IntPtr.Zero);
    }


}

VB.NET:

Public Class Utils
    <System.Runtime.InteropServices.DllImport("user32.dll", CharSet := System.Runtime.InteropServices.CharSet.Auto)> _
    Private Shared Function SendMessage(hWnd As System.IntPtr, wMsg As Integer, wParam As System.IntPtr, lParam As System.IntPtr) As Integer
    End Function

    Private Const WM_VSCROLL As Integer = &H115
    Private Const SB_BOTTOM As Integer = 7

    ''' <summary>
    ''' Scrolls the vertical scroll bar of a multi-line text box to the bottom.
    ''' </summary>
    ''' <param name="tb">The text box to scroll</param>
    Public Shared Sub ScrollToBottom(tb As System.Windows.Forms.TextBox)
        If System.Environment.OSVersion.Platform <> System.PlatformID.Unix Then
            SendMessage(tb.Handle, WM_VSCROLL, New System.IntPtr(SB_BOTTOM), System.IntPtr.Zero)
        End If
    End Sub


End Class

উইন্ডোজ 10 এর ক্ষেত্রেও একই সমস্যা ছিল, আপনার কাজটি এখানেও ঠিকঠাক কাজ করে।
হ্যানস

কেউই আমার পক্ষে কাজ করছিল না, তবে এটি।
Yourশ্বর

9

আমার একটি রিফ্রেশ যুক্ত করতে হবে:

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

4

আমি একটি সাধারণ পার্থক্য পেয়েছি যা এই থ্রেডে সম্বোধন করা হয়নি।

আপনি যদি ScrollToCarat()আপনার ফর্মের Load()ইভেন্টের অংশ হিসাবে সমস্ত কল করছেন তবে এটি কার্যকর হয় না। আমি ScrollToCarat()আমার ফর্মের Activated()ইভেন্টে আমার কলটি যুক্ত করেছি , এবং এটি দুর্দান্ত কাজ করে।

সম্পাদন করা

প্রথমবারের ফর্মের Activatedইভেন্টটি চালিত হওয়ার পরে কেবল এই স্ক্রোলিং করা গুরুত্বপূর্ণ (পরবর্তী ক্রিয়াকলাপগুলিতে নয়), বা প্রতিবার আপনার ফর্মটি সক্রিয় হওয়ার সাথে সাথে এটি স্ক্রোল করবে , যা সম্ভবত আপনি চান না is

সুতরাং আপনি যদি Activated()আপনার প্রোগ্রামটি লোড হয় যখন আপনি কেবলমাত্র আপনার পাঠ্যটি স্ক্রোল করতে ইভেন্টটি আটকাচ্ছেন, তবে আপনি কেবল ইভেন্ট হ্যান্ডলারের ভিতরে থাকা ইভেন্টটির সাবস্ক্রাইব করতে পারেন:

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

আপনার ফর্মটি সক্রিয় হওয়ার সময় আপনার যদি অন্য কিছু করার দরকার হয় তবে boolআপনার Activated()ইভেন্টটি প্রথমবার চালিত হওয়ার পরে আপনি সত্যটি সেট করতে পারেন , যাতে আপনি পরবর্তী ক্রিয়াকলাপগুলিতে স্ক্রোল না করেন, তবে আপনার অন্যান্য প্রয়োজনীয় জিনিসগুলি এখনও করতে পারেন না।

এছাড়াও, যদি আপনার TextBoxএকটি ট্যাব চালু থাকে নয় SelectedTab, ScrollToCarat()কোন প্রভাব ফেলবে না। সুতরাং আপনি যখন স্ক্রল করছেন তখন আপনাকে এটিকে নির্বাচিত ট্যাব তৈরি করতে হবে। আপনি কোডটি একটিতে মুড়ে ফেলতে পারেন YourTab.SuspendLayout();এবং YourTab.ResumeLayout(false);যদি আপনি এটি করেন তখন আপনার ফর্মটি ফ্লিকার হয়।

সম্পাদনার সমাপ্তি

আশাকরি এটা সাহায্য করবে!


1

পাঠ্যটি পরিবর্তিত হয়ে গেলে এটি পাঠ্যবক্সের শেষের দিকে স্ক্রোল করবে তবে এখনও ব্যবহারকারীকে স্ক্রোল আপ করতে দেয়

outbox.SelectionStart = outbox.Text.Length;
outbox.ScrollToEnd();

ভিজ্যুয়াল স্টুডিও এন্টারপ্রাইজ 2017 এ পরীক্ষিত


1

ওয়েবফর্ম বাস্তবায়ন দেখার প্রত্যাশায় অন্য যে কেউ এখানে অবতরণ করছেন, আপনি পৃষ্ঠা অনুরোধ পরিচালকের শেষপর্যায়ের ইভেন্ট হ্যান্ডলারটি ব্যবহার করতে চান ( https://stackoverflow.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);

0

এটি কেবল আমার পক্ষে কাজ করেছিল ...

txtSerialLogging-> পাঠ্য = "";

txtSerialLogging-> AppendText (গুলি);

আমি উপরের সমস্ত ক্ষেত্রে চেষ্টা করেছি, তবে সমস্যাটি আমার ক্ষেত্রে পাঠ্য হ্রাস পেতে পারে, বাড়তে পারে এবং দীর্ঘ সময়ের জন্য স্থির থাকতে পারে। স্থির অর্থ, স্থির দৈর্ঘ্য (লাইন) তবে সামগ্রী পৃথক।

সুতরাং, যখন আমি দৈর্ঘ্য (রেখাগুলি) কিছু সময়ের জন্য একই থাকত তখন আমি এক লাইনের জাম্পিং পরিস্থিতির মুখোমুখি হয়েছি ...


আমি জানি, এটি বব এর উত্তরের অনুরূপ, তবে একটি নির্দিষ্ট কেস ব্যাখ্যা করে। এবং আমি বব এর জবাব সম্পর্কে মন্তব্য করতে পারি না ...
স্ট্যাকওভারফ্লো

0

আমি এর জন্য একটি ফাংশন ব্যবহার করি:

private void Log (string s) {
    TB1.AppendText(Environment.NewLine + s);
    TB1.ScrollToCaret();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.