I have a C# application wherein there are two multiline textboxes side-by-side, each in one side of a split-container. I would like to synchronize their vertical scroll, so that when the user scrolls up or down one of the textboxes, the other textbox scrolls respectively in the same direction. Is there a way to do this? Thanks.
ADDITIONAL INFORMATION - 7/26/10
I found some interesting APIs on the MSDN website:
TextBox.GetFirstVisibleLineIndex Method
TextBox.GetLastVisibleLineIndex Method
TextBox.ScrollToLine Method
The documentation there looks promising, but my compiler (Microsoft Visual C# 2008 Express Edition) complains when I try to use it, even after adding the PresenationFramework
as a Reference and inserting using System.Windows.Controls;
at the top of the file:
Error 1 'System.Windows.Forms.TextBox' does not contain a definition for 'GetFirstVisibleLineIndex' and no extension method 'GetFirstVisibleLineIndex' accepting a first argument of type 'System.Windows.Forms.TextBox' could be found (are you missing a using directive or an assembly reference?)
ADDITIONAL INFORMATION - 7/27/10
I'm working on implementing Jay's suggestion of implementing a new control, but I'm having trouble tying the eventhandler into the control. Here's is what I have so far:
public partial class MyFormApplication : Form
{
public MyFormApplication() // MyFormApplication constructor
{
this.InitializeComponent();
this.textBox1.Dispose(); // Replacing with textBoxSync1
this.textBox2.Dispose(); // Replacing with textBoxSync2
// Draw textBoxSync1
this.textBoxSync1.AcceptsReturn = true;
this.textBoxSync1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxSync1.BackColor = System.Drawing.SystemColors.Control;
this.textBoxSync1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBoxSync1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxSync1.Location = new System.Drawing.Point(0, 19);
this.textBoxSync1.Multiline = true;
this.textBoxSync1.Name = "textBoxSync1";
this.textBoxSync1.ReadOnly = true;
this.textBoxSync1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBoxSync1.Size = new System.Drawing.Size(338, 231);
this.textBoxSync1.TabIndex = 0;
this.textBoxSync1.TabStop = false;
this.textBoxSync1.WordWrap = false;
this.splitContainer1.Panel1.Controls.Remove(this.textBox1);
this.splitContainer1.Panel1.Controls.Add(this.textBoxSync1);
// Draw textBoxSync2
this.textBoxSync2.AcceptsReturn = true;
this.textBoxSync2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxSync2.BackColor = System.Drawing.SystemColors.Control;
this.textBoxSync2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBoxSync2.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxSync2.Location = new System.Drawing.Point(0, 19);
this.textBoxSync2.Multiline = true;
this.textBoxSync2.Name = "textBoxSync2";
this.textBoxSync2.ReadOnly = true;
this.textBoxSync2.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBoxSync2.Size = new System.Drawing.Size(113, 231);
this.textBoxSync2.TabIndex = 30;
this.textBoxSync2.TabStop = false;
this.textBoxSync2.WordWrap = false;
this.splitContainer1.Panel2.Controls.Remove(this.textBox2);
this.splitContainer1.Panel2.Controls.Add(this.textBoxSync2);
/* Goes on to perform other initializations... */
}
private void textBoxSync1_VerticalScroll(Message msg)
{
msg.HWnd = this.textBoxSync2.Handle;
this.textBoxSync2.PubWndProc(ref msg);
}
private void textBoxSync2_VerticalScroll(Message msg)
{
msg.HWnd = this.textBoxSync1.Handle;
this.textBoxSync1.PubWndProc(ref msg);
}
}
public class TextBoxSynchronizedScroll : System.Windows.Forms.TextBox
{
public event vScrollEventHandler VerticalScroll;
public delegate void vScrollEventHandler(System.Windows.Forms.Message message);
public const int WM_VSCROLL = 0x115;
protected override void WndProc(ref System.Windows.Forms.Message msg)
{
if (msg.Msg == WM_VSCROLL)
{
if (VerticalScroll != null)
{
VerticalScroll(msg);
}
}
base.WndProc(ref msg);
}
public void PubWndProc(ref System.Windows.Forms.Message msg)
{
base.WndProc(ref msg);
}
}
I should think that something like...
this.textBoxSync1.VerticalScroll += new System.EventHandler(this.textBoxSync1_VerticalScroll);
...would be needed to hook the vertical scroll event into the control, but as you can probably see, this does not work. Any suggestions would be appreciated. Thanks.