基本上我在Form上有两个列表框syncListView1和syncListView2(windows表单应用程序)我试图让他们的滚动条同步
我搜索了一些,我发现了这个类,但它似乎不起作用:
class SyncListBox : System.Windows.Forms.ListBox
{
[Category("Action")]
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
public event ScrollEventHandler OnHorizontalScroll;
public event ScrollEventHandler OnVerticalScroll;
private const int SB_LINEUP = 0;
private const int SB_LINELEFT = 0;
private const int SB_LINEDOWN = 1;
private const int SB_LINERIGHT = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGELEFT = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGERIGHT = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_PAGETOP = 6;
private const int SB_LEFT = 6;
private const int SB_PAGEBOTTOM = 7;
private const int SB_RIGHT = 7;
private const int SB_ENDSCROLL = 8;
private const int SIF_TRACKPOS = 0x10;
private const int SIF_RANGE = 0x1;
private const int SIF_POS = 0x4;
private const int SIF_PAGE = 0x2;
private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetScrollInfo(
IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo);
private struct ScrollInfoStruct
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}
protected override void WndProc(ref System.Windows.Forms.Message msg)
{
if (msg.Msg == WM_HSCROLL)
{
if (OnHorizontalScroll != null)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_ALL;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(msg.HWnd, 0, ref si);
if (msg.WParam.ToInt32() == SB_ENDSCROLL)
{
ScrollEventArgs sargs = new ScrollEventArgs(
ScrollEventType.EndScroll,
si.nPos);
OnHorizontalScroll(this, sargs);
}
}
}
if (msg.Msg == WM_VSCROLL)
{
if (OnVerticalScroll != null)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_ALL;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(msg.HWnd, 0, ref si);
if (msg.WParam.ToInt32() == SB_ENDSCROLL)
{
ScrollEventArgs sargs = new ScrollEventArgs(
ScrollEventType.EndScroll,
si.nPos);
OnVerticalScroll(this, sargs);
}
}
}
base.WndProc(ref msg);
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// scrolled
//
this.Size = new System.Drawing.Size(120, 95);
this.ResumeLayout(false);
}
}
并在后面的代码中:
private void syncListView2_OnVerticalScroll(object sender, ScrollEventArgs e)
{
syncListView1.TopIndex = syncListView2.TopIndex;
}
private void syncListView1_OnVerticalScroll(object sender, ScrollEventArgs e)
{
syncListView2.TopIndex = syncListView1.TopIndex;
}
答案 0 :(得分:1)
这对于copy/paste code from article来说真是不好的做法,甚至懒得阅读有关代码和用户评论的所有内容。你并不是第一个被困在这个地方的人....因为one user already commented the problem
所以你可能错过的是订阅活动。有两种选择:
syncListView1_OnVerticalScroll
。使用第二个列表框执行相同操作,但选择syncListView1_OnVerticalScrol2
在您有列表框打开代码视图的表单中。应该有构造函数调用InitializeComponent()
方法。在该方法之后添加以下代码行。
syncListView1.OnVerticalScroll + = this.syncListView1_OnVerticalScroll; syncListView2.OnVerticalScroll + = this.syncListView2_OnVerticalScroll;
答案 1 :(得分:1)
您不需要派生类SyncListBox
只需在Windows窗体的InitializeComponent()或windows窗体构造函数中附加事件处理程序,如下所示
EventHandler handler = (s,e) =>{
if (s == syncListView1)
syncListView2.TopIndex = syncListView1.TopIndex;
if (s == syncListView2)
syncListView1.TopIndex = syncListView2.TopIndex;
};
this.syncListView1.MouseCaptureChanged += handler;
this.syncListView2.MouseCaptureChanged += handler;
this.syncListView1.SelectedIndexChanged += handler;
this.syncListView2.SelectedIndexChanged += handler;
答案 2 :(得分:0)
另一个例子......这个让你保持原始.Net ListBox到位,只需将它们传递给Form的Load()事件中的SyncListBoxes的构造函数。这将处理垂直滚动,鼠标滚轮滚动,以及当ListBoxes作为键盘输入的结果滚动时(通过SelectedIndexChanged事件):
public partial class Form1 : Form
{
private SyncListBoxes _SyncListBoxes = null;
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
this._SyncListBoxes = new SyncListBoxes(this.syncListView1, this.syncListView2);
}
}
public class SyncListBoxes
{
private ListBox _LB1 = null;
private ListBox _LB2 = null;
private ListBoxScroll _ListBoxScroll1 = null;
private ListBoxScroll _ListBoxScroll2 = null;
public SyncListBoxes(ListBox LB1, ListBox LB2)
{
if (LB1 != null && LB1.IsHandleCreated && LB2 != null && LB2.IsHandleCreated &&
LB1.Items.Count == LB2.Items.Count && LB1.Height == LB2.Height)
{
this._LB1 = LB1;
this._ListBoxScroll1 = new ListBoxScroll(LB1);
this._ListBoxScroll1.Scroll += _ListBoxScroll1_VerticalScroll;
this._LB2 = LB2;
this._ListBoxScroll2 = new ListBoxScroll(LB2);
this._ListBoxScroll2.Scroll += _ListBoxScroll2_VerticalScroll;
this._LB1.SelectedIndexChanged += _LB1_SelectedIndexChanged;
this._LB2.SelectedIndexChanged += _LB2_SelectedIndexChanged;
}
}
private void _LB1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this._LB2.TopIndex != this._LB1.TopIndex)
{
this._LB2.TopIndex = this._LB1.TopIndex;
}
if (this._LB2.SelectedIndex != this._LB1.SelectedIndex)
{
this._LB2.SelectedIndex = this._LB1.SelectedIndex;
}
}
private void _LB2_SelectedIndexChanged(object sender, EventArgs e)
{
if (this._LB1.TopIndex != this._LB2.TopIndex)
{
this._LB1.TopIndex = this._LB2.TopIndex;
}
if (this._LB1.SelectedIndex != this._LB2.SelectedIndex)
{
this._LB1.SelectedIndex = this._LB2.SelectedIndex;
}
}
private void _ListBoxScroll1_VerticalScroll(ListBox LB)
{
if (this._LB2.TopIndex != this._LB1.TopIndex)
{
this._LB2.TopIndex = this._LB1.TopIndex;
}
}
private void _ListBoxScroll2_VerticalScroll(ListBox LB)
{
if (this._LB1.TopIndex != this._LB2.TopIndex)
{
this._LB1.TopIndex = this._LB2.TopIndex;
}
}
private class ListBoxScroll : NativeWindow
{
private ListBox _LB = null;
private const int WM_VSCROLL = 0x115;
private const int WM_MOUSEWHEEL = 0x20a;
public event dlgListBoxScroll Scroll;
public delegate void dlgListBoxScroll(ListBox LB);
public ListBoxScroll(ListBox LB)
{
this._LB = LB;
this.AssignHandle(LB.Handle);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case WM_VSCROLL:
case WM_MOUSEWHEEL:
if (this.Scroll != null)
{
this.Scroll(_LB);
}
break;
}
}
}
}
答案 3 :(得分:-1)
将列表框类型更改为SyncListBox并附加到OnVerticalScroll事件。
//Omitted for brevity
private SyncListBox listBox1;
private SyncListBox listBox2;
//Omitted for brevity
this.listBox1 = new WindowsFormsApplication1.SyncListBox();
this.listBox2 = new WindowsFormsApplication1.SyncListBox();
//Omitted for brevity
listBox1.OnVerticalScroll += listBox1_OnVerticalScroll;
listBox2.OnVerticalScroll += listBox2_OnVerticalScroll;
//Event handlers
void listBox2_OnVerticalScroll(object sender, ScrollEventArgs e)
{
listBox1.TopIndex = listBox2.TopIndex;
}
void listBox1_OnVerticalScroll(object sender, ScrollEventArgs e)
{
listBox2.TopIndex = listBox1.TopIndex;
}