[英]Synchronizing Multiline Textbox Positions in C#
我有一個C#應用程序,其中有兩個並排的多行文本框,每個文本框位於拆分容器的一側。 我想同步它們的垂直滾動,這樣當用戶向上或向下滾動其中一個文本框時,另一個文本框分別向同一方向滾動。 有沒有辦法做到這一點? 謝謝。
其他信息 - 7/26/10
我在MSDN網站上找到了一些有趣的API:
TextBox.GetFirstVisibleLineIndex方法
TextBox.GetLastVisibleLineIndex方法
TextBox.ScrollToLine方法
那里的文檔看起來很有希望,但是當我嘗試使用它時,我的編譯器(Microsoft Visual C#2008 Express Edition)會抱怨,即使在將PresenationFramework
作為引用添加並using System.Windows.Controls;
插入之后也是PresenationFramework
using System.Windows.Controls;
在文件的頂部:
錯誤1'System.Windows.Forms.TextBox'不包含'GetFirstVisibleLineIndex'的定義,並且沒有可以找到接受類型'System.Windows.Forms.TextBox'的第一個參數的擴展方法'GetFirstVisibleLineIndex'(你錯過了嗎?使用指令或程序集引用?)
其他信息 - 7/27/10
我正在努力實現Jay的實現新控件的建議,但是我無法將eventhandler綁定到控件中。 這是我到目前為止所擁有的:
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);
}
}
我應該認為......
this.textBoxSync1.VerticalScroll += new System.EventHandler(this.textBoxSync1_VerticalScroll);
...需要將垂直滾動事件掛鈎到控件中,但正如您可能看到的,這不起作用。 任何建議,將不勝感激。 謝謝。
我將RichTextBox子類化並監聽WM_VSCROLL消息以執行您要執行的操作。 也許你可以這樣做,而不是使用TextBox。
回復您的編輯:
注意:我假設您在復制並粘貼到應用程序表單中時出現了一個小錯誤,而且textBoxSyncBusTraffic == textBoxSync1
問題出在你的控件的VerticalScroll事件聲明中,在這一行:
this.textBoxSyncBusTraffic.VerticalScroll += new System.EventHandler(this.textBoxSyncBusTraffic_VerticalScroll);
所以改變這個:
this.textBoxSyncBusTraffic.VerticalScroll += new System.EventHandler(this.textBoxSyncBusTraffic_VerticalScroll);
對此:
this.textBoxSync1.VerticalScroll += new TextBoxSynchronizedScroll.vScrollEventHandler(textBoxSync1_VerticalScroll);
這使用正確的事件處理程序並引用您需要和已有的方法。
另外,請確保textBoxSync2的VerticalScroll事件的聲明如下所示:
this.textBoxSync2.VerticalScroll += new TextBoxSynchronizedScroll.vScrollEventHandler(textBoxSync2_VerticalScroll);
順便提一下,您可以使用幾種技術來更輕松地聲明事件:
首先是使用表單設計器。 如果在窗體設計器中的擴展控件實例的“屬性”窗口中打開“事件”窗口,則會看到名為VerticalScroll的事件。 雙擊此項以使Visual Studio聲明事件並創建一個在事件觸發時調用的方法。
在代碼中設置事件時,還可以使用快捷方式。 鍵入以下代碼后,您會發現:
youtextBoxSync1.VerticalScroll +=
系統將提示您按Tab鍵完成聲明。 如果這樣做,Visual Studio將創建一個具有正確簽名的方法。
根據現有代碼,我提出了以下內容。 似乎為我工作。
class TextBoxSynchronizedScroll : TextBox
{
public const int WM_VSCROLL = 0x115;
List<TextBoxSynchronizedScroll> peers = new List<TextBoxSynchronizedScroll>();
public void AddPeer(TextBoxSynchronizedScroll peer)
{
this.peers.Add(peer);
}
private void DirectWndProc(ref Message m)
{
base.WndProc(ref m);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL)
{
foreach (var peer in this.peers)
{
var peerMessage = Message.Create(peer.Handle, m.Msg, m.WParam, m.LParam);
peer.DirectWndProc(ref peerMessage);
}
}
base.WndProc(ref m);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.