且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C#Windows窗体中的作物区域选择控件(如photoshop的)

更新时间:2023-12-06 11:45:40

在这里需要考虑的是创建一个自己的用户控件,该控件封装了一个矩形.此控件将负责矩形的实际绘制,但更重要的是,它将知道如何调整其大小.我知道这只是重复您已经说过的内容,但请耐心等待一下.

此控件应在每条线的角和中心绘制迷你矩形;这些将代表您的抓握手柄.当在这些控制矩形中的任何一个内部按下鼠标时,可以根据鼠标拖动移动的方向调整矩形的大小.现在,您可以执行某些优化操作-不要在每次移动时都重新绘制矩形-相反,您可以应用一个小的偏移量,以便矩形一旦经过偏移量后才重新绘制.要确定您是否在抓取框中,可以使用Rectangle.Contains来查看鼠标的位置是否在该抓取框中(有趣的是,这是我今天第二次建议使用此方法-必须成为今天的事情.

我希望这会给您一些有关设计的思考.
What you need to think about doing here is create yourself a UserControl that encapsulates a rectangle. This control will be responsible for the actual drawing of the rectangle, but more importantly, will know how to resize itself. I know that this is just repeating what you have already said, but bear with me for a moment.

This control should have mini rectangles drawn at the corners, and in the centre of each line; these will represent your grab handles. When the mouse is pressed down inside any of these control rectangles, then the rectangle can be resized depending on the direction of the mouse drag movement. Now, there are certain optimisations you can do - don''t redraw the rectangle at every move - instead, you could apply a small offset so that the rectangle is only repainted once it passes the offset. To determine if you''re in a grab box, you could use Rectangle.Contains to see if the mouse location is in that grab box (funnily enough, this is the second time I''ve recommended using this method today - there must be something about today).

I hope this gives you something to think about for the design.


除了Pete在回答中提供的设计思想之外,我还要强调一点,您不应该使用.您需要做的是从System.Windows.Forms.Control派生的自定义控件,并在事件Paint的处理程序中进行所有呈现,或者更好的是在覆盖的受保护虚拟方法OnPaint中进行所有呈现.
PictureBox仅适用于静态图片的简单表示,可能会不时替换.将此类用于任何交互式,动态的动画,都是对此类动画的滥用.在这种情况下,PictureBox不会提供任何好处,只会给开发带来更多麻烦.它只是吞噬了一些额外的资源,性能和开发时间,却没有任何回报.

我在过去的回答中对此进行了详细说明:
如何从旧图纸中清除面板 [ ^ ],
在C#中绘制矩形 [ Paint是一种哪种好玩的方法? (DataGridViewImageCell.Paint(...)) [在mdi子表单之间画线 [在面板上捕获图形 [
In addition to the idea of the design Pete offered in his answer, I would like to emphasize that you should not use PictureBox. All you need is a custom control derived from System.Windows.Forms.Control and do all the rendering in the handler of the event Paint or, better yet, in the overridden protected virtual method OnPaint.

The PictureBox is good only for simple presentation of a static picture, maybe replaced from time to time. Using this class for anything interactive, dynamic of animated is the abuse of it. In such cases, PictureBox does not provide any benefits, only extra hassles in development; it simply eats up some extra resources, performance and your development time offering nothing in return.

I explain it in detail in my past answers:
How do I clear a panel from old drawing[^],
draw a rectangle in C#[^].

See also my other past answers on related topics:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^].

—SA