对于Multiline = True的System.Windows.Forms.TextBox,我只想在文本不适合时显示滚动条.
这是仅用于显示的只读文本框.它是一个TextBox,以便用户可以复制文本.是否有任何内置支持滚动条的自动显示?如果没有,我应该使用不同的控件吗?或者我是否需要挂钩TextChanged并手动检查溢出(如果是,如何判断文本是否适合?)
没有任何运气与WordWrap和Scrollbars设置的各种组合.我想最初没有滚动条,只有当文本不适合给定的方向时才会动态显示.
@nobugz,谢谢,当WordWrap被禁用时有效.我不想禁用wordwrap,但它是两个邪恶中较小的一个.
@AndréNeves,好的一点,如果是用户可编辑的话,我会这样做.我同意一致性是UI直观性的基本规则.
当我想解决同样的问题时,我遇到了这个问题.
最简单的方法是更改为System.Windows.Forms.RichTextBox.在这种情况下,ScrollBars属性可以保留为默认值RichTextBoxScrollBars.Both,它表示"在需要时显示水平和垂直滚动条".如果在TextBox上提供此功能,那将是很好的.
在项目中添加一个新类并粘贴下面显示的代码.编译.将新控件从工具箱顶部拖放到表单上.它不是很完美,但应该适合你.
using System; using System.Drawing; using System.Windows.Forms; public class MyTextBox : TextBox { private bool mScrollbars; public MyTextBox() { this.Multiline = true; this.ReadOnly = true; } private void checkForScrollbars() { bool scroll = false; int cnt = this.Lines.Length; if (cnt > 1) { int pos0 = this.GetPositionFromCharIndex(this.GetFirstCharIndexFromLine(0)).Y; if (pos0 >= 32768) pos0 -= 65536; int pos1 = this.GetPositionFromCharIndex(this.GetFirstCharIndexFromLine(1)).Y; if (pos1 >= 32768) pos1 -= 65536; int h = pos1 - pos0; scroll = cnt * h > (this.ClientSize.Height - 6); // 6 = padding } if (scroll != mScrollbars) { mScrollbars = scroll; this.ScrollBars = scroll ? ScrollBars.Vertical : ScrollBars.None; } } protected override void OnTextChanged(EventArgs e) { checkForScrollbars(); base.OnTextChanged(e); } protected override void OnClientSizeChanged(EventArgs e) { checkForScrollbars(); base.OnClientSizeChanged(e); } }
我还做了一些实验,发现如果启用它,垂直条将始终显示,并且水平条始终显示,只要它已启用并且WordWrap == false
.
我想你不会在这里得到你想要的东西.但是,我相信用户希望Windows的默认行为比您试图强制的更好.如果我使用你的应用程序,如果我的文本框房地产突然缩小,我可能会感到困扰,因为它需要容纳一个意想不到的滚动条,因为我给了它太多的文本!
也许让您的应用程序遵循Windows的外观和感觉是个好主意.
在nobugz的解决方案中有一个非常微妙的错误导致堆损坏,但前提是你使用AppendText()更新TextBox.
从OnTextChanged设置ScrollBars属性将导致Win32窗口(句柄)被销毁并重新创建.但是OnTextChanged是从Win32编辑控件(EditML_InsertText)的内部调用的,之后立即要求Win32编辑控件的内部状态保持不变.不幸的是,由于窗口被重新创建,操作系统已释放该内部状态,从而导致访问冲突.
所以故事的寓意是:如果你打算使用nobugz的解决方案,请不要使用AppendText().