在C#中,当面板滚动时自动垂直滚动RichTextBox

3

我在WinForm中的面板里有一个RichTextBox。我想隐藏RichTextBox的垂直滚动条,并将其滚动与容器面板的垂直滚动条同步;每当textbox中的文本溢出时,面板的滚动条应该出现,每当我滚动面板的滚动条时,textbox应该滚动。


你的面板只包含 RichTextBox 吗? - King King
是的,它只有一个RichTextBox。 - jeff
这可能需要使用一些技巧来完成,但是要使它像RichTextBox的真正垂直滚动条一样工作,您必须处理一些win32消息,这并不容易。例如,如果您使用“向上”或“向下”箭头键将插入符号向上或向下移动,滚动条拇指也应相应移动,还有其他情况... - King King
2个回答

2

正如我在评论中所说的,我们必须处理win32消息并使用一些技巧。我已经运用了我所有关于win32消息和控件hack/定制的知识,在winforms中为您制作了这个演示。它不完整,当然也不会像RichTextBox的标准滚动条那样完美。不足之处在于,如果你一直按住箭头键,滚动条拇指就不会向右移动,但是如果你正常按下箭头键,滚动条拇指将像标准滚动条一样将插入符号移到视图中。你可以尝试自己运行代码来看它的效果:

public class Form1 : Form {
   [DllImport("user32")]
   private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
   public Form1(){
      InitializeComponent();
      //initialize some properties for your richTextBox1 (this should be added as a child of your panel1)
      richTextBox1.ScrollBars = RichTextBoxScrollBars.Horizontal;
      richTextBox1.BorderStyle = BorderStyle.None;
      richTextBox1.Dock = DockStyle.Top;
      richTextBox1.MinimumSize = new Size(panel1.Width, panel1.Height - 2);
      //initialize some properties for your panel1
      panel1.AutoScroll = true;
      panel1.BorderStyle = BorderStyle.FixedSingle;       
      //If the size of panel1 is changed, we have to update the MinimumSize of richTextBox1.
      panel1.SizeChanged += (s,e) => {
         richTextBox1.MinimumSize = new Size(panel1.Width, panel1.Height - 2);
      };   
      new NativeRichTextBox() { Parent = panel1 }.AssignHandle(richTextBox1.Handle);
      hidden.Parent = panel1;    
   }
   //hidden control of panel1 is used to scroll the thumb when the KeyUp of richTextBox1 is raised.
   Control hidden = new Control();
   //this is used to hook into the message loop of the richTextBox1
   public class NativeRichTextBox : NativeWindow
    {
        public Panel Parent;
        protected override void WndProc(ref Message m)
        {

            if (m.Msg == 0x20a)//WM_MOUSEWHEEL = 0x20a
            {                    
                if (Parent != null)
                {
                    SendMessage(Parent.Handle, m.Msg, m.WParam, m.LParam);                     
                    return;
                }
            }
            base.WndProc(ref m);                
        }
    }
   //ContentsResized event handler of your richTextBox1
   private void richTextBox1_ContentsResized(object sender, ContentsResizedEventArgs e)
    {
        richTextBox1.Height = e.NewRectangle.Height + 5;            
    }
   //KeyUp event handler of your richTextBox1
   private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
    {
            Point p = richTextBox1.GetPositionFromCharIndex(richTextBox1.SelectionStart);                                
            hidden.Top = panel1.PointToClient(richTextBox1.PointToScreen(p)).Y;
            hidden.Height = (int) richTextBox1.SelectionFont.Height;
            panel1.ScrollControlIntoView(hidden);                
    }
}

注意:您需要使用代码或设计工具为您的 richTextBox1 注册事件处理程序 ContentsResizedKeyUp


0

为了隐藏滚动条,您可以执行以下操作

richTextBox1.ScrollBars = RichTextBoxScrollBars.None;

但它的问题在于它会使文本变形,因此您还需要

richTextBox1.WordWrap = false;

一旦你完成了这个,剩下的也不是那么容易了。

在面板滚动事件上注册并更改富文本框上的滚动。问题是你不能只改变richTextBox的滚动偏移量,所以你可以使用Select方法跳转到需要的位置。你可以使用行的长度来知道scrollBar需要的大小。

最后,这将是一项艰苦的工作。祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接