方向性平移和滚动工具箱项
提供详细文档的源代码,可编译为控件库 (DLL)。
引言
面板是一个很好的容器,因为东西会“固定”在面板上;将面板的Click()事件与由该面板上的滚动/平移按钮激活的计时器挂钩,可以快速完成按钮布局的组织和计时器启动/停止事件与单个按钮上的鼠标按下/抬起事件的协调工作,前提是有一个像Btn9Panel这样的方便类,其中包含构造函数和方法,一旦Visual Studio设计器看到它,并且在它到达工具箱之前,这些构造函数和方法就可以准备好布局所有细节。
背景
我见过的大多数CodeProject文章都涉及需要数小时才能弄清楚的复杂问题,虽然有时对于初学者来说存在相当明显和简单的解决方案,但大多数文章都涉及相对复杂或曲折的场景。显然,一旦读者完成了真正棘手的事情,他们就没有时间去处理简单的事情了,所以我认为我应该提供一些节省时间的代码……也许可以给穷人一个晚上多睡十五分钟的机会。
Using the Code
只需将Btn9Panel从工具箱拖到一个窗体上,就可以看到它的作用。HorizPanel和VertPanel类继承自Btn9Panel,您可以将这三者都拖到一个窗体上,并使用设计器来更改尺寸或FlatAppearance元素,当使用FlatStyle.Flat时,这些元素是可用的。
代码本身并没有什么特别棘手的问题需要在这里讨论。NineBtnCtrl.DLL源代码的文档记录非常详尽(甚至过度),您应该在Visual Studio IDE中查看它,以便在逐节查看时能够打开和关闭每个区域的折叠。完全折叠它,然后一次只检查一个部分,会比在这里全部看完所需的时间少得多。
将其中一个面板拖到窗体后,您只需要“连接”以下代码:
btn9Panel1.Click +=new EventHandler(btn9Panel1_Click);
btn9Panel1.Enable();
在窗体的InitializeComponent()语句之后。并且还需要面板的Click()事件处理程序。
private void btn9Panel1_Click(object sender, EventArgs e) 
{ /* Call your scroll/pan code here */ }
Btn9Form.cs中的示例仅执行两个操作来演示处理程序中的“滚动”。
ii = ii + btn9Panel1.Dx; jj = jj + btn9Panel1.Dy; 
每次计时器滴答时,使用.DLL代码提供的[+|-]1的Dx和Dy增量,您就可以进行平移、滚动、更改数组索引或执行任何其他需要的操作;只要鼠标按钮保持按下状态,计时器就会持续生成这些增量并调用您的代码。因此,您只需要决定如何进行滚动;如果您因为某种原因不想使用计时器,可以调用SetDxDy()来为您设置Dx和Dy,这样您就可以使用相同的代码以编程方式以及响应鼠标按钮事件进行滚动。当您想关闭对按钮按键的计时器响应时,调用btn9Panel1.Disable();并且请务必检查,如.DLL源代码中所述,在调用您应用程序中精确控制的代码之前,如果要在关键时期启用或禁用计时器,请检查BtnDown是否为true。
Btn9Form.cs中的示例Windows窗体提供了一个运行包含按钮矩阵的窗体的机会,并允许您在查看效果的同时更改MouseOver、MouseDown、Background、Border和Checked颜色(设计器在设计图面上不显示MouseOver或MouseDown颜色,仅在属性窗口中显示);在退出窗体后,您可以使用设计器中的属性对话框来设置默认颜色或面板尺寸,尽管如果您对自己的偏好非常执着,也可以将新值硬编码到.DLL源代码中并重新编译。
 
 
Btn9Form.cs在按钮按下期间,还会显示面板名称、按钮名称、按钮索引和方向(W、NW、N等),同时两个整数值会递增/递减。顾名思义,只有两个按钮的两个子类只会沿N-S或E-W方向滚动,前提是您的滚动代码遵循常规的地图约定。
关注点
我最初为两个独立的项目编写了一些滚动代码,我打算最终合并它们,但它们不能互操作。其中一个片段的运行方式类似于模态对话框,尽管线程模型并非如此,也没有调用BackgroundWorker类,因为我将它们联系在了一起。我最初在一个项目中使用BackgroundWorker,在另一个项目中使用第二个Thread,并使用一套相当复杂的信号量来启用、配置、启动、控制、停止和禁用前一个片段中的工作线程;而后者使用一套更简单但仍然相似的信号量,尽管后者提供了双向滚动而前者没有。区别在于,后者的滚动事件由八个按钮(与这里展示的Btn9Panel在同一个窗体中)启动和停止,这些按钮仅滚动单个图形图像窗口;而前者的滚动事件由十二个按钮(与这里展示的VertPanel在同一个窗体中)启动和停止,并且可以按需同步滚动一个数组中的虚拟窗口和一个PictureBox中的可见窗口,该窗口对应于该数组并包含数组内容的位图表示。
尽管在合并这两个片段时,我用一个计时器替换了BackgroundWorker和第二个Thread,但我没有像您在HorizPanel和VertPanel中看到的那样合并和继承按钮的布局,也没有为双向Btn9Panel创建一个单独的类。这些类是专门为这个CodeProject文章创建的,仅仅因为我认为将这些实现所体现的功能提炼成一个单一的、易于使用和易于设置的工具箱项的想法值得一试。
历史
Btn9Panel的开发工作源于我的项目“CQvis MultiGradient Palette Tool”,这是一个免费软件程序,您可以在许多网站上下载。该程序有一个Thread在其中进行滚动,但并不使用Start()、Suspend()、Sleep()或Stop()方法来启动或终止滚动,如果您使用WinDbg或PEBrowse Professional来检查它,您就会看到。第二个进程线程在程序运行的整个时间内都在连续运行,其行为完全由信号量控制。




