01.窗体自动显示滚动条
方式一(利用窗体的AutoScroll属性):
设置窗体的AutoScroll属性为true,自适应窗体上的子控件上的布局,如果窗体内的子控件超出了窗体的范围,窗体就会自动出现滚动条。
方式二(利用窗体的AutoScrollMinSize属性):
当窗体尺寸变小后,让其自动显示滚动条,只需在Form1_Load()函数中增加一句代码:
private void Form1_Load(object sender, EventArgs e)
{
this.AutoScrollMinSize = new Size(ClientRectangle.Width, ClientRectangle.Height);
}
注解:
AutoScrollMinSize属性读取或者设置form的客户区域或者也叫文档区域,也就是工作的区域。如果设置的区域大于form当前的大小,则窗体会自动出现滚动条。
02.绘图时异常现象
现在窗体上绘制一个椭圆, 代码如下:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.FillEllipse(Brushes.LightGreen, 20, 20, 300, 200);
}
程序运行结果如下图所示,出现了不愿意看到的结果。
原因:
Graphics对象绘制图形时并不知道滚动条的变化情况,默认情况下它总是以“工作区左上角”为原点绘制图形的,即它描点时的坐标总是参照“工作区左上角”的。
当拖动滚动条时,也会触发Paint事件,重新绘制工作区,但系统并不重新绘制整个工作区。当滚动条向下拖动50像素时,系统首先把工作区中的图像整体向上平移50像素,这时工作区下部出现一块大小为300×50像素的空白,系统只需补上这块空白区域即可。这种按需绘制的方式可以大大提高绘图效率。
然而这块空白区域纵坐标范围为150~200,正好是椭圆上半部分的位置,所以Graphics对象把椭圆上半部分重新绘制了一遍,结果就出现了椭圆上半部分出现两次的情况
所以要想正确绘制出空白区域的图形,需要把绘图的坐标原点向上平移50像素,而这一点可以通过坐标的平移变换实现.坐标平移的情况如图2所示,要绘制从A点开始的区域,就要把坐标系原点由工作区的左上角A平移到文档的左上角O,即始终使坐标系的原点位于文档的左上角。这种变换可以通过下面的语句实现。
g.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
属性AutoScrollPosition表示的是滚动条的位置,滚动条移动了多少像素,坐标系就要平移多少像素。需要注意的是,AutoScrollPosition.X和AutoScrollPosition.Y均为负数,所以坐标原点实际上是向左上角平移的。
改进后的代码:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
//平移坐标系
g.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
g.FillEllipse(Brushes.LightGreen, 20, 20, 300, 200);
}
03.自定义控件中添加滚动条
现在自定义一个用户控件,用户控件在窗体上只有200 * 150 的大小。
同样要在这个用户控件的矩形区域(20, 20, 300, 200)中绘制一个椭圆,代码如下:
private void Form1_Load(object sender, EventArgs e)
{
userControl11.AutoScrollMinSize = new Size(350, 250); // 其实就是设置用户控件的工作区域
// 当控件大小比工作区域小时,就会出现滚动条
}
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void UserControl1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y);
g.FillEllipse(Brushes.LightGreen, 20, 20, 300, 200);
}
}
04.捕捉滚动条事件
重载滚动条的Scroll方法即可:
private void UserControl1_Scroll(object sender, ScrollEventArgs e)
{
Debug.WriteLine(e.Type.ToString() + " -- " + e.NewValue);
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll) // 水平滚动条事件
{
}
else if (e.ScrollOrientation == ScrollOrientation.VerticalScroll) // 垂直滚动条事件
{
}
}
关于e.Type:
LargeDecrement 滚动框移动了较长的距离。用户在滚动条上单击了滚动框左侧(水平)或上方(垂直),或者按了 Page Up 键。
LargeIncrement 滚动框移动了较长的距离。用户在滚动条上单击了滚动框右侧(水平)或下方(垂直),或者按了 Page Down 键。
SmallDecrement 滚动框移动了较短的距离。用户单击了左(水平)或上(垂直)滚动箭头,或者按了向上键。
SmallIncrement 滚动框移动了较短的距离。用户单击了右(水平)或下(垂直)滚动箭头,或者按了向下键。
ThumbPosition 滚动框被移动。
ThumbTrack 滚动框当前正在移动。
。。。
更多内容,请查阅文档:《C#滚动条使用总结.edg》
下载地址:
http://download.csdn.net/detail/xingyu_soft/9424968
文档目录