簡體   English   中英

在C#中同步多行文本框位置

[英]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); 
  1. 您的自定義控件需要訂閱控件的TextBoxSynchronizedScroll.vScrollEventHandler事件(而不是System.EventHandler)。
  2. 事件處理程序中引用的方法不存在(至少不在您發布的代碼中)。

所以改變這個:

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);
    }
}

http://gist.github.com/593809

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM