精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。”需要全文内容也请联系孙老师。
This control was originally developed to mimic some existing software that my company was using to view and process medical claims. The original plan was to develop a PictureBox that would allow the users to draw a box on the image and then zoom in on that point. It was immediately apparent that this would be no easy task.该控件最初是为了模仿我公司用于查看和处理医疗索赔的一些现有软件而开发的。最初的计划是开发一个PictureBox允许用户在图像上绘制一个框然后放大该点的方案。很明显,这不是一件容易的事。
The PictureBoxEx still uses .NET 1.1 to make it more compatible with current and future projects, but has been completely rewritten.
This control is a completely new control, it is no longer based on a PictureBox but a ScrollableControl. Making this switch was necessary to create a control that was both flexible and fast. When drawing the drag window, the old control was slow to build the image and refresh, whereas the new control is very smooth.
This new version also contains the ability to add annotations to the images. These annotations can be colored, resized to match the image's current zoom, and best of all are XmlSerializable, so they can be saved to file and retrieved later.
PictureBoxEx仍然使用.NET 1.1,使其与当前和未来的项目更兼容,但已完全重写。
这个控件是一个全新的控件,它不再基于PictureBox而是ScrollableControl。进行此切换对于创建既灵活又快速的控件是必要的。绘制拖动窗口时,旧控件构建图像和刷新速度很慢,而新控件非常流畅。
此新版本还包含向图像添加注释的功能。这些注释可以着色,调整大小以匹配图像的当前缩放,最重要的是XmlSerializable,因此可以将它们保存到文件中并在以后检索。
Scrolling was also added to this new control. The control now has the ability to be scrolled vertically and horizontally, by both the keys and the mouse. Scrolling the wheel causes the image to be scrolled vertically, but if you hold the control key while scrolling the mouse wheel, the image can now be scrolled horizontally. The arrow keys plus Home, End, PageUp, PageDown can all be used to scroll the image. Because the control is unable to receive and hold direct focus, the focus can shift from control to control on the same form. So to make use of the key scrolling, it is best to make this PictureBoxEx the only control on the form. (If anyone knows how to improve this limitation, I would love to hear about it.)
Also the current zoom of the control can be changed by scrolling the mouse wheel while holding the shift key down.
滚动也被添加到这个新控件。控件现在可以通过键和鼠标垂直和水平滚动。滚动滚轮会导致图像垂直滚动,但如果在滚动鼠标滚轮的同时按住控件键,则图像现在可以水平滚动。箭头键加上Home,End,PageUp,PageDown都可用于滚动图像。由于控件无法接收并保持直接对焦,因此焦点可以在同一表格上从控件转换为控件。因此,要使用键滚动,最好将PictureBoxEx其作为窗体上的唯一控件。(如果有人知道如何改善这个限制,我很乐意听到它。)
此外,可以通过按住shift键的同时滚动鼠标滚轮来更改控件的当前缩放。
Most of the controls custom properties are available through the designer.大多数控件自定义属性都可以通过设计器获得。
The following code is used by GenerateResizedImage to generate the resized image from the backup which is created when the Image property of the control is set. The creating of the resized image happens regardless of the current zoom, even if it's 1. The reason it's generated anyway is because the control can't work with images of an indexed pixel format. So it's just easier to convert the images straight away.以下代码让GenerateResizedImage处理从备份生成大小变更的Image,这个Image是在Image属性设置时创建。无论当前缩放如何,都会创建调整大小的图像,即使它是1.无论如何生成它的原因是因为控件无法处理索引像素格式的图像。因此,直接转换图像会更容易。
int resizedWidth = Convert.ToInt32(backup.Width * _currentZoom);
int resizedHeight = Convert.ToInt32(backup.Height * _currentZoom);
resized = new Bitmap(resizedWidth, resizedHeight);
// Drag the backup image onto the resized image
using (Graphics g = Graphics.FromImage(resized))
{
g.InterpolationMode = (_currentZoom < 1F) ?
_drawMode : InterpolationMode.Default;
Rectangle srceRect =
new Rectangle(0, 0, backup.Width, backup.Height);
Rectangle destRect =
new Rectangle(0, 0, resized.Width, resized.Height);
g.DrawImage(backup, destRect, srceRect, GraphicsUnit.Pixel);
// Add any annotations to the resized image
DrawAnnotations(g);
}
Determining where the zoom should occur requires a lot of math. The first step it to compensate for the current zoom and the current scroll position. Then, it needs to be determined which part of the drag window is larger in proportion to the size of the control, and enlarge that section to fill the control while centering the remainder.
确定缩放应该发生的位置需要大量的数学运算。它是补偿当前缩放和当前滚动位置的第一步。然后,需要确定拖动窗口的哪个部分与控件的尺寸成比例地变大,并且在使剩余部分居中的同时放大该部分以填充控件。
// The zoom window will never be proportional to the container, so one
// side will get filled while the other gets centered. The larger % will
// determine which gets filled, and which gets centered
float xRatio = (float)Width / (float)dragWindowSave.Width;
float yRatio = (float)Height / (float)dragWindowSave.Height;
float largerRatio;
int xAdjust = 0;
int yAdjust = 0;
largerRatio = (xRatio < yRatio) ? xRatio : yRatio;
// The cumulative zoom cannot exceed the maximum zoom;
if ((largerRatio * _currentZoom) > _maximumZoom)
largerRatio = _maximumZoom / _currentZoom;
if (dragWindowSave.Width * largerRatio > Width)
largerRatio = (float)Width / (float)dragWindowSave.Width;
if (dragWindowSave.Height * largerRatio > Height)
largerRatio = (float)Height / (float)dragWindowSave.Height;
yAdjust = Convert.ToInt32(
((float)Height - (float)dragWindowSave.Height * largerRatio) / 2F);
xAdjust = Convert.ToInt32(
((float)Width - (float)dragWindowSave.Width * largerRatio) / 2F);
int xScrollPos = Math.Max(Convert.ToInt32(((float)-AutoScrollPosition.X +
(float)dragWindowSave.X) * largerRatio) - xAdjust, 0);
int yScrollPos = Math.Max(Convert.ToInt32(((float)-AutoScrollPosition.Y +
(float)dragWindowSave.Y) * largerRatio) - yAdjust, 0);
CurrentZoom *= largerRatio;
The control is very much like a PictureBox. All that really needs to be done is to add the control to a form and set its Image property.
控件非常像一个PictureBox。所有真正需要做的就是将控件添加到表单并设置其Image属性。