/// <summary> /// 创建框选框 /// </summary> /// <returns></returns> private Rectangle CreateSelectionRectangle() { Point mousePoint = _imageListView.PointToClient(Cursor.Position); Point lastMouseDownLocation = _imageListView.LastMouseDownLocation; #region 说明 //当框选的同时,滚动滚动条 //计算offset: //由于可视区域和项的一般显示区域之间有个padding,而滚动条是以内部区域为标准的 //所以当滚动条开始滚动时,可能项还是全部显示在可视范围内的(padding区也可以显示) //那么此时 _itemsBoundsOffset 还是 0,而按下鼠标时 _mouseDownOffset 记录的也是当时的 _itemsBoundsOffset //那么在计算 SelectionRectangle 的 Y 坐标时, //如果直接用 _itemsBoundsOffset 参与计算,就会产生一个和padding有关的误差 //如 lastMouseDownLocation.Y - (viewOffset - _mouseDownOffset) ,假如此时向下滚动了一点 //但所有的项还在可视范围内,那么 就会是 lastMouseDownLocation.Y - (0 - 0) //SelectionRectangle 的 Y 坐标就差生了误差 //解决的办法是使用 _itemsAreaOffset(既滚动条的Value),使框框的Y坐标与滚动条同步滚动即可 #endregion int viewOffset = _itemsAreaOffset; Point pt1 = new Point(lastMouseDownLocation.X, lastMouseDownLocation.Y - (viewOffset - _mouseItemsAreaOffset)); Point pt2 = new Point(mousePoint.X, mousePoint.Y); Rectangle rect = new Rectangle(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y), Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y)); return(rect); }