如何在附加文本时阻止TextBox自动滚动?
我有一个带有垂直滚动条的多行TextBox,它可以记录实时进程中的数据。 目前,每当textBox.AppendText()
添加新行时,TextBox都会滚动到底部,这样您就可以看到最后一个条目,这很棒。 但我有一个复选框来决定何时允许TextBox自动滚动。 反正有没有这样做?
注意:
如果我们有一个解决方案,那么还有一个问题是当TextBox附加文本时,当用户使用滚动条查看TextBox中的其他位置时,如何防止TextBox自动滚动?
private void OnTextLog(string text) { if (chkAutoScroll.Checked) { // This always auto scrolls to the bottom. txtLog.AppendText(Environment.NewLine); txtLog.AppendText(text); // This always auto scrolls to the top. //txtLog.Text += Environment.NewLine + text; } else { // I want to append the text without scrolls right here. } }
更新1 :正如saggio建议的那样,我也认为这个问题的解决方案是确定当前文本中第一个字符在TextBox中显示的位置,然后再附加文本并在之后恢复它。 但是怎么做呢? 我试着像这样记录当前的光标位置,但它没有帮助:
int selpoint = txtLog.SelectionStart; txtLog.AppendText(Environment.NewLine); txtLog.AppendText(text); txtLog.SelectionStart = selpoint;
更新2 (问题已解决) :我找到了一个可以在Stack Overflow上解决我的问题的解决方案 。 我已经优化了他们的代码以适应我的问题,如下所示:
// Constants for extern calls to various scrollbar functions private const int SB_VERT = 0x1; private const int WM_VSCROLL = 0x115; private const int SB_THUMBPOSITION = 0x4; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetScrollPos(IntPtr hWnd, int nBar); [DllImport("user32.dll")] private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); [DllImport("user32.dll")] private static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam); [DllImport("user32.dll")] private static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos); private void AppendTextToTextBox(TextBox textbox, string text, bool autoscroll) { int savedVpos = GetScrollPos(textbox.Handle, SB_VERT); textbox.AppendText(text + Environment.NewLine); if (autoscroll) { int VSmin, VSmax; GetScrollRange(textbox.Handle, SB_VERT, out VSmin, out VSmax); int sbOffset = (int)((textbox.ClientSize.Height - SystemInformation.HorizontalScrollBarHeight) / (textbox.Font.Height)); savedVpos = VSmax - sbOffset; } SetScrollPos(textbox.Handle, SB_VERT, savedVpos, true); PostMessageA(textbox.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * savedVpos, 0); } private void OnTextLog(string text) { AppendTextToTextBox(txtLog.Text, Environment.NewLine + text, chkAutoScroll.Checked); }
其他方式:
private const int SB_VERT = 0x1; private const int WM_VSCROLL = 0x115; private const int SB_THUMBPOSITION = 0x4; private const int SB_BOTTOM = 0x7; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetScrollPos(IntPtr hWnd, int nBar); [DllImport("user32.dll")] private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); [DllImport("user32.dll")] private static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam); private void AppendTextToTextBox(TextBox textbox, string text, bool autoscroll) { int savedVpos = GetScrollPos(textbox.Handle, SB_VERT); textbox.AppendText(text + Environment.NewLine); if (autoscroll) { PostMessageA(textbox.Handle, WM_VSCROLL, SB_BOTTOM, 0); } else { SetScrollPos(textbox.Handle, SB_VERT, savedVpos, true); PostMessageA(textbox.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * savedVpos, 0); } }
我为那些有类似问题的人发布了这些解决方案。 感谢cgyDeveloper的源代码。
有没有人有更简单的方法?
这似乎很简单,但我可能会遗漏一些东西。 如果Autochecked为true,则使用追加文本滚动到该位置,如果您不想滚动,只需添加文本。
更新……我错过了什么。 您想要设置选择点,然后滚动到插入符号。 见下文。
if (chkAutoScroll.Checked) { // This always auto scrolls to the bottom. txtLog.AppendText(Environment.NewLine); txtLog.AppendText(text); // This always auto scrolls to the top. //txtLog.Text += Environment.NewLine + text; } else { int caretPos = txtLog.Text.Length; txtLog.Text += Environment.NewLine + text; txtLog.Select(caretPos, 0); txtLog.ScrollToLine(txtLog.GetLineIndexFromCharacterIndex(caretPos)); }
你必须这样做,
textBox1.AppendText("Your text here"); // this selects the index zero as the location of your caret textBox1.Select(0, 0); // Scrolls to the caret :) textBox1.ScrollToCaret();
测试和使用VS2010 c#Winforms,我不知道WPF但谷歌可能有你的答案。
上述就是C#学习教程:如何在附加文本时阻止TextBox自动滚动?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/990274.html