介绍 此示例演示如何
访问从System.Windows.Forms派生的自定义控件中的滚动条事件。列表框控件,在c# . net。问题回答: 如何获得滚动事件? 如何获得滚动条的位置? 开始 创建一个新的项目(文件,新建,项目…),类型为“Windows应用程序”。Visual Studio将在解决方案资源管理器和'Form1 '中显示该项目。设计模式下的cs。右键单击项目节点并选择‘Add, Add User Control…’。命名为“ScrollingListBox.cs”。现在可以在解决方案资源管理器中看到它,并且在设计器中看起来像一个灰色的正方形。 按F7进入代码并将基本的'UserControl'替换为'ListBox'。保存,编译,转到设计器。如您所见,解决方案资源管理器中的图标发生了变化,设计器没有显示列表框。这是您此时的代码:收缩,复制Code
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; namespace WebsiteSamples { /// <summary> /// Summary description for ScrollingListBox. /// </summary> public class ScrollingListBox : System.Windows.Forms.ListBox { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public ScrollingListBox() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitForm call } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion } }
Win32的东西 我们将重写WndProc并处理滚动条事件。这是常数的名称相同的C:\Program Files\Microsoft Visual Studio . net \ Vc7 \ PlatformSDK \ \ WinUser.h包括包含文件。隐藏,复制Code
private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; private const int SB_LINELEFT = 0; private const int SB_LINERIGHT = 1; private const int SB_PAGELEFT = 2; private const int SB_PAGERIGHT = 3; private const int SB_THUMBPOSITION = 4; private const int SB_THUMBTRACK = 5; private const int SB_LEFT = 6; 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;
当我们在WndProc中识别滚动消息时,我们需要调用user32.dll中的GetScrollInfo来查找位置。(微软文档说,当类型是SB_THUMBPOSITION或SB_THUMBTRACK时,这个位置在滚动消息的wparam中发送,但这根本不是真的。)因此,首先从DLL中导入GetScrollInfo。隐藏,复制Code
[DllImport("user32.dll", SetLastError=true) ] private static extern int GetScrollInfo( IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo );
在Win32中,ScrollInfoStruct被称为SCROLLINFO,这是您在Microsoft api中看到的典型查询构造:信息结构被装载有自己的大小和问题代码(以及问题的可选参数)。在这种情况下,问题是‘你的立场是什么?”,或“SIF_ALL”。隐藏,复制Code
private struct ScrollInfoStruct { public int cbSize; public int fMask; public int nMin; public int nMax; public int nPage; public int nPos; public int nTrackPos; }
最后,检测消息并触发事件 好的,现在让我们在收到滚动消息时启动标准ScrollEvent。为此,我们需要事件,我将其称为“滚动”,因为这是微软对事件(如“Clicked”)的命名:复制Code
[Category("Action")] public event ScrollEventHandler Scrolled = null;
在WndProc中,获取滚动消息并触发滚动事件。在这个例子中,我只响应WM_HSCROLL消息,因为这是一个所有者绘制列表框控件所需要的消息。然而,WM_VSCROLL的代码完全相同。在本例中,我只对滚动结束消息感兴趣,它是在每个滚动动作之后触发的。隐藏,复制Code
protected override void WndProc(ref System.Windows.Forms.Message msg) { if( msg.Msg == WM_HSCROLL ) { if( Scrolled != 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); Scrolled(this, sargs); } } } base.WndProc(ref msg); }
为了能够使用Marshal类,您必须引用互操作名称空间:Hide复制Code
using System.Runtime.InteropServices;
应该做的。您可以通过捕获垂直滚动条或捕获更多滚动事件来扩展它。如果您想知道滚动条在其他任何时候的位置,请使用GetScrollInfo函数。 另外,我还没有尝试过,但它可能适用于任何带有滚动条的控件。 如果你想知道,我需要这段代码有其他控件'滚动'与列表框。 本文转载于:http://www.diyabc.com/frontweb/news273.html