一: 基本控件的布局
1.首先,我们先新建一个UserControl自定义控件,拖拽一个Panel容器至界面窗口,Dock停靠模式选择Fill,即我们将画面填满容器.
2.然后,再拖拽一个PictureBox至上一步的Panel容器内部,同样的Dock停靠模式选择Fill.
3.选择一张好看的图给PictrueBox的image属性赋值.全都做好后,如下图所示啦
二: 交互事件原理及编写
原理:整体框架是通过对picturebox的位置和大小变换实现图像的平移及缩放操作.而panel作为父窗体起着控制移动和缩放显示范围的作用.
首先来了解一下平移,平移无非是Picturebox的top和left属性的更改,怎样确定x及y轴的平移量的问题.从Picturebox原本的位置移动到鼠标的位置e.X,e.Y(Cursor.Position.X,Cursor.Position.Y);由于鼠标坐标是相对于屏幕计算的,不能直接将鼠标位置赋给Picturebox.我们通过记录鼠标左键按下的位置与之后鼠标移动时的位置差来获取这个平移量,然后将其附加到Picturbox实现控件的平移.
而缩放,采用倍率缩放的模式(scale=0.2),即Picturebox的Widht和Height属性直接加上放大或缩小倍率之后的值实现缩放操作,此时注意Left和top属性也要跟着变动,不然放大中心就不是鼠标位置了,鼠标滚轮前滚e.Delta值为正,鼠标滚轮后滚e.Delta值为负,乘以e.Delta的符号来决定是放大了还是缩小了
废话不多说,上菜:
public System.Drawing.Point mouseDownPoint;//存储鼠标焦点的全局变量
public bool isSelected = false;//平移状态
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Dock = DockStyle.None;
//这个事件是鼠标滑轮滚动的触发事件,可以在Designer.cs中注册。
this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseWheel);
this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
}
/// <summary>
/// 滚轮缩放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
double scale = 0.2;
int width = pictureBox1.Width;
int height = pictureBox1.Height;
int left = PointToClient(Cursor.Position).X - pictureBox1.Left;
int top = PointToClient(Cursor.Position).Y - pictureBox1.Top;
int sign = Math.Sign(e.Delta);
pictureBox1.Width += (int)(sign * scale * width);
pictureBox1.Height += (int)(sign * scale * height);
this.pictureBox1.Left -= (int)(sign * scale * left);
this.pictureBox1.Top -= (int)(sign * scale * top);
}
//在MouseDown处获知鼠标是否按下,并记录下此时的鼠标坐标值;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint.X = Cursor.Position.X; //注:全局变量mouseDownPoint前面已定义为Point类型
mouseDownPoint.Y = Cursor.Position.Y;
isSelected = true;
}
}
//在MouseUp处获知鼠标是否松开,终止拖动操作;
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isSelected = false;
}
/// <summary>
/// 判断鼠标是否在父窗口内移动
/// </summary>
/// <returns></returns>
private bool IsMouseInPanel()
{
if (this.panel_Picture.Left < PointToClient(Cursor.Position).X
&& PointToClient(Cursor.Position).X < this.panel_Picture.Left
+ this.panel_Picture.Width && this.panel_Picture.Top
< PointToClient(Cursor.Position).Y && PointToClient(Cursor.Position).Y
< this.panel_Picture.Top + this.panel_Picture.Height)
{
return true;
}
else
{
return false;
}
}
//图片平移,在MouseMove处添加拖动函数操作
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isSelected && IsMouseInPanel())//确定已经激发MouseDown事件,和鼠标在picturebox的范围内
{
this.pictureBox1.Left = this.pictureBox1.Left + (Cursor.Position.X - mouseDownPoint.X);
this.pictureBox1.Top = this.pictureBox1.Top + (Cursor.Position.Y - mouseDownPoint.Y);
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
}
}
/// <summary>
/// 双击还原
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel_Picture_DoubleClick(object sender, EventArgs e)
{
this.pictureBox1.Left = 0;
this.pictureBox1.Top = 0;
this.pictureBox1.Width = panel_Picture.Width;
this.pictureBox1.Height = panel_Picture.Height;
}