最近在做一个项目,有个功能点是需要把图片根据鼠标滚轮的滚动放大或缩小。
然后就查资料,找到 PictureBox 控件有个鼠标滚轮的事件:
//
// 摘要:
// 在控件有焦点且鼠标轮移动时发生。
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Advanced)]
[SRCategoryAttribute("CatMouse")]
[SRDescriptionAttribute("ControlOnMouseWheelDescr")]
public event MouseEventHandler MouseWheel;
这个事件在控件属性面板是不显示的,因为 [Browsable(false)] 是不显示的。
事件由控件可以点出来。
pic_Show.MouseWheel += new MouseEventHandler(Pic_Show_MouseWheel);
实现功能思路:
1.鼠标按下左键,移动鼠标,图片移动,鼠标抬起,停止移动。
(这里有三个事件,按下,移动,抬起)
2.鼠标滚轮实现缩放功能。
(这里有一个事件,鼠标滚轮事件)
实例的界面布局如图:
下面是完整代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PhotoControl
{
public partial class FrmMain : Form
{
private bool IsMouseMove = false;//判断鼠标是不是在移动
private Point MousePoint;//记录鼠标按下时的位置
public FrmMain()
{
InitializeComponent();
com_ScaleValue.SelectedIndex = 0;//默认选择缩放值是10
//MouseWheel事件在控件属性列表里是不可见的,但是它确实是存在的。因为可以点出来这个事件。
pic_Show.MouseWheel += new MouseEventHandler(Pic_Show_MouseWheel);
}
/// <summary>
/// 选择图片的按钮事件方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_OpenPic_Click(object sender, EventArgs e)
{
OpenFileDialog openFile = new OpenFileDialog();//打开文件对话框
if (openFile.ShowDialog() == DialogResult.OK)
{
txt_PicPath.Text = openFile.FileName;
LoadPic(openFile.FileName);
}
}
//把图片加载到控件上
private void LoadPic(string picPath)
{
pic_Show.Image = null;//先清除图片
pic_Show.Image = Image.FromFile(picPath);//在加载图片
}
//鼠标按键按下
private void pic_Show_MouseDown(object sender, MouseEventArgs e)
{
if (pic_Show.Image == null)//鼠标按下先判断是否有图片,如果没有则没反应
{
return;
}
if (e.Button == MouseButtons.Left)//判断是否是鼠标左键
{
//鼠标按下时的位置
MousePoint.X = Cursor.Position.X;
MousePoint.Y = Cursor.Position.Y;
IsMouseMove = true;//当鼠标按下时认为它要移动
pic_Show.Focus();
}
}
//鼠标移动
private void pic_Show_MouseMove(object sender, MouseEventArgs e)
{
if (pic_Show.Image == null)
{
return;
}
pic_Show.Focus();//图片获取焦点
if (IsMouseMove)
{
int newLocX, newLocY; //移动新位置的x,y坐标
int lengthX, lengthY; //x,y两个方向移动的长度
lengthX = Cursor.Position.X - MousePoint.X;
lengthY = Cursor.Position.Y - MousePoint.Y;
newLocX = pic_Show.Location.X + lengthX;
newLocY = pic_Show.Location.Y + lengthY;
pic_Show.Location = new Point(newLocX, newLocY);
MousePoint.X = Cursor.Position.X;
MousePoint.Y = Cursor.Position.Y;
}
}
//鼠标按键抬起
private void pic_Show_MouseUp(object sender, MouseEventArgs e)
{
//如果鼠标按键抬起,就停止移动
if (e.Button == MouseButtons.Left)
{
IsMouseMove = false;
}
}
//鼠标滚轮
private void Pic_Show_MouseWheel(object sender, MouseEventArgs e)
{
if (pic_Show.Image == null)
{
return;
}
PictureBox newPic = pic_Show;
int x = e.Location.X;//鼠标的x
int y = e.Location.Y;//鼠标的y
int w = newPic.Width;//图片的宽
int h = newPic.Height;//图片的高
int vectorX, vectorY;//因缩放产生的位移矢量
if (e.Delta > 0) //放大
{
if (newPic.Width > 650)
{
return;
}
//放大就是增加新图的宽和高
newPic.Width += Convert.ToInt32(com_ScaleValue.Text);
newPic.Height += Convert.ToInt32(com_ScaleValue.Text);
//利用反射获取新图的矩形宽高信息
PropertyInfo pInfo = newPic.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
Rectangle rect = (Rectangle)pInfo.GetValue(newPic, null);
//把放大后的宽高赋值给控件
newPic.Width = rect.Width;
newPic.Height = rect.Height;
}
if (e.Delta < 0) //缩小
{
//防止一直缩成负值
if (newPic.Width < 150)
return;
//缩小就是减小新图的宽和高
newPic.Width -= Convert.ToInt32(com_ScaleValue.Text);
newPic.Height -= Convert.ToInt32(com_ScaleValue.Text);
//利用反射获取新图的矩形宽高信息
PropertyInfo pInfo = newPic.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
BindingFlags.NonPublic);
Rectangle rect = (Rectangle)pInfo.GetValue(newPic, null);
//把缩小后的宽高赋值给控件
newPic.Width = rect.Width;
newPic.Height = rect.Height;
}
//因缩放产生的位移,进行补偿,实现锚点缩放的效果
vectorX = (int)((double)x * (w - newPic.Width) / w);
vectorY = (int)((double)y * (h - newPic.Height) / h);
newPic.Location = new Point(newPic.Location.X + vectorX, newPic.Location.Y + vectorY);
}
}
}
在这里记录一下,以便以后遇到。