Windows Mobile .NET 应用程序中的垂直滚动条宽度





3.00/5 (1投票)
为特定控件设置垂直滚动条宽度

引言
在开发一个针对不同 Windows Mobile/CE/PocketPC 设备的应用程序时,我需要支持不同的屏幕。当我需要支持一个 2.5 英寸的屏幕设备,并且需要用手指操作(没有笔)时,我遇到了一个问题。Windows Mobile 的默认滚动条宽度是 13 像素,这对于在这样小的显示器上用手指点击来说绝对太小了。本文介绍了一种解决方法,可以在不改变操作系统标准宽度的情况下,只让应用程序中的特定滚动条变宽。
背景
“.NET Framework 非常强大,提供了许多现成的功能。因此,当你遇到一个简单功能不仅在 .NET Framework 中不可用,而且使用 PInvoke 或其他类似方法也极其难以处理时,会更加令人沮丧。”
“为一个简单的面板设置滚动条的宽度就是这样一种简单但棘手的任务。 .NET Framework 有一个用于垂直滚动条的类(VScrollBar
),它会在像 panel 这样的可滚动控件上显示一个滚动条。但你无法以任何方式访问它们的滚动条。我在网上搜索了这个主题,找到了几个建议,但它们都有至少一个缺点:”
- “通过修改注册表来更改整个操作系统的滚动条:需要重启,会改变它们的所有应用程序和所有滚动条。”
- “编写自己的容器控件:不方便,需要实现现有功能。”
- “使用反射查找可滚动控件的表示滚动条的 `private` 成员:不幸的是,这在 Windows Mobile 上不起作用。”
“于是我开始思考如何使用标准的 VScrollBar
控件来覆盖并模仿标准滚动条的功能。在我的一次搜索中,我偶然发现了 Peter Foot 的关于滚动控件的 文章,这是一个很好的起点:它展示了一种以编程方式滚动控件的方法。所以我的第一个想法是按照标准方式配置我的滚动条,并使用这段代码滚动它。但这只起到了部分作用,因为我无法猜出微软用于确定滚动条的最小值和最大值以及它们的步长(行步长和页步长)的公式。此外,也没有办法跳转到特定位置,只能跳转一个‘行’或一个‘页’。”
“使用一些 PInvoke 方法,我成功获取了原始滚动控件的最小和最大值以及页步长。行步长在滚动信息中不可用,所以我只是‘猜测’它对于面板是 3 像素,并将其设为一个常量。”
“现在唯一剩下的就是,当用户更改我的滚动条时,将标准滚动条滚动到相同的位置。起初,我尝试跳转一些页面和一些行,以尽可能接近所需位置。但这很笨拙、缓慢且不准确。于是我想到了另一个主意:更改原始滚动控件的页步长,跳转一页,然后恢复页步长。说起来容易做起来难,因为微软似乎只在所有事件处理完毕后才会关注你通过 SetScrollInfo
发送的任何更改。我通过在设置滚动信息后调用 Application.DoEvents()
解决了这个问题,并取得了不错的效果。”
“最后一步是将所有这些打包成一个方便使用的扩展方法。这是最容易的部分。”
Using the Code
“要使用这段代码,请按照以下步骤操作:”
- “将文件 ScrollBarHelperEx.cs 添加到您的项目中。”
- “为您的项目添加对
Microsoft.Windowsce.Forms
的引用。” - “在带有面板的窗体中添加一个
using
子句using IESoft;
” - “将面板的
AutoScroll
属性设置为true
。” - “将所有控件添加到面板中。”
- “调用面板的
SetVScrollBarWidth
方法,该方法只有一个参数:新的滚动条宽度(以像素为单位)。”
for (int i = 0; i < 8; i++)
{
var b1 = new Button();
b1.Text = "Button " + i;
b1.Width = this.label1.Width;
b1.Location = new Point(this.label1.Left, this.label1.Bottom +
i * b1.Height + (i + 1) * 5);
this.panel1.Controls.Add(b1);
var b2 = new Button();
b2.Text = "Button " + i;
b2.Width = this.label2.Width;
b2.Location = new Point(this.label2.Left, this.label2.Bottom +
i * b2.Height + (i + 2) * 5);
this.panel2.Controls.Add(b2);
}
this.panel2.SetVScrollBarWidth(40);
关注点
“我真的不明白为什么微软不直接或间接地为我们提供处理如此简单任务的可能性。我从 CodeProject 获得了许多解决此类问题的方案,希望通过本文能帮助到其他人。”
已知问题和可能的增强功能
我在我的解决方案中发现了一些问题:
- “快速上下滚动时,滚动条有时会不同步。连续滚动通常会修复此问题。”
- “如果在添加所有控件之前设置滚动条的宽度,自定义滚动条将不正确。通过重置自定义滚动条可以轻松修复此问题,但我没有添加此功能,因为我不需要它。”
“我能想到几种可能的增强功能:”
- “添加相同的功能来设置水平滚动条的高度。有了现成的代码,这非常简单直接。”
历史
- “首次创建于 2010 年 5 月 10 日。”