建议:在PictureBox之间拖放 [英] Suggestion: Drag and Dropping Between PictureBoxes
问题描述
我提供了2张图片,以便您更轻松地理解我的问题, 由于我是新成员,因此无法在此处直接链接它们,因此我将它们放在了Dropbox的公共文件夹中,
I have included 2 images so you can understand my question easier, I could not link them directly in here as I am a new member, so I have put them in my Dropbox public folder,
图片1:设计"视图 https://www.dropbox.com/s/wca5gstd8kdsie7/designView.png ?dl = 0
在这里您可以在左侧看到组面板", 嵌套有6个较小的盒子,它们都是图片框",
Here you can see a Group Panel on the left, With 6 smaller boxes nested they are all "pictureBoxes",
然后在右边是一个较大的图片框,其中一个较小的图片框嵌套在其中,
Then on the right is a larger picture Box, with a smaller one nested inside,
图像2应用程序正在运行 https://www.dropbox.com/s/u5bknooks17of1r/appView.png ?dl = 0
在这里您可以看到左侧加载的图像(请忽略图像的失真,这是我会在之后解决的问题)
Here you can see the images loaded on the left (Please ignore the distortion of the images, this is something I will fix after)
我需要做的是将一些图像(短语)从左侧拖动到右侧的圆圈中的段"中,
What I need to do, is drag some images (the phrases) from the left hand side, into the circle in the right hand side, within the "segments",
然后,我想保存圆圈,并将新图像拖放到圆圈上(我将执行drawToBitmap),我只想知道对我而言最好的方法是什么?
Then I want to save the circle, with the new images that have been dragged on top of it (which I will do a drawToBitmap), I just want to know what is the best way for me to go about this?
请提出一些建议,
我现在可以在左侧移动图像,但是由于当前只能在其图片框内移动而只能移动很小的图像,
I can move the images on the left at the moment, but only a tiny amount as they are currently restricted to only move within their picture Box,
推荐答案
您的问题包括三个任务:
Your problem consists of three tasks:
- 移动
Controls
(在这里为PictureBoxes
). - 检查以查看他们降落的地方
- 放置它们,使它们加入目标区域
- Moving
Controls
(here:PictureBoxes
) around. - Checking to see where they have landed
- Placing them in a way that makes them join in the target area
以下是有关每个任务的一些提示:
Here are a few hints about each task:
- 要移动
Controls
,最好使用MouseDown
存储起点,并使用MouseMove
事件更新移动控件的Location
.在MouseUp
事件中,您可以完成操作:也许处理命中,重置控件,输出用户消息等.
- To move the
Controls
it is best to use theMouseDown
to store a starting point and theMouseMove
event to update theLocation
of the moving control. And in theMouseUp
event you can finalize the action: Maybe process the hit, reset the control, output user messages, etc..
请注意,事件属于您要移动的每个控件,但是如果将它们映射到所有控件的相同三个事件,则可以使用sender
参数向右移动Control
.比重复相同的代码n次要好得多.
Note that the events belong to each control you to move, but if you map them to the same three events for all controls you can use the sender
parameter to move the right Control
. Much better than repeating the same code n times..
(一个人甚至可以编写一个可重用的函数makeMoveable(Control ctl)
以使任何Control
都可移动;这可能涉及三个事件的三个lambda
表达式.)
(One can even write a reusable function makeMoveable(Control ctl)
to make any Control
moveable; this could involve three lambda
expressions for the three events..)
还要注意,如果您的控件最初位于某个容器内,则说一个Panel
,您将需要将其Parent
更改为最好的Form
;在这里,您还需要根据原始父对象的偏移量来调整位置,并且需要使用BringtoFront()
使它们移到窗体上所有其他控件的上方.
Also note that if your controls originally sit inside some container, say a Panel
you will need to change their Parent
to be, probably best, the Form
; here you also will need to adapt the location by the offset of the original parent and you need to use BringtoFront()
to make them move above all other controls on the Form..
- 对于命中测试,您需要检查新位置是否在圆弧段内.段的形状比
Rectangle
更复杂.复杂的形状可以通过在GraphicsPath
中添加简单的内容来构造.
- For hit testing you need to check if the new location is inside a segment of a circle. A segment is a more complicated shape than, say a
Rectangle
. Complicated shapes can be constructed by adding simple things to aGraphicsPath
.
Rectangles
还具有Rectangle.Contains(Point)
功能,因此似乎更易于命中测试.出于特殊原因,GraphicsPaths
的相同功能被命名为GraphicsPath.IsVisible(Point)
.
Rectangles
also seem easier for hit testing since they have a Rectangle.Contains(Point)
function. For no special reason the same function for GraphicsPaths
goes by the name GraphicsPath.IsVisible(Point)
.
- 如果您有组成整个圆圈的
GraphicsPaths
列表,则可以使用它来限制绘图,并在使用Graphics.SetClip(segment)
后直接将正确的图像绘制到圆圈上.
- If you have a list of
GraphicsPaths
that make up the full circle you can use it to restrict the drawing and draw the right image directly onto the circle after usingGraphics.SetClip(segment)
.
为了让您开始使用细分,这里是一个创建细分并将其绘制在Paint
事件中的PictureBox
pb_target上的函数.请注意,两个Arcs
的绘制方向相反,因此Closing
Path
不会创建交叉连接!
To get you going with segments here is a function that creates a segment and paints it onto a PictureBox
pb_target in its Paint
event. Note that the two Arcs
are drawn in opposite directions so that Closing
the Path
will not create crossing connections!
List<GraphicsPath> segments = new List<GraphicsPath>();
private void Form4_Load(object sender, EventArgs e)
{
PointF center = new PointF(pb_target.Width / 2f, pb_target.Height / 2f);
float angle = 60f;
for (int i = 0; i < 360 / angle; i++)
{
segments.Add(getSegment(center, pb_target.Width / 2.5f,
pb_target.Width / 4f, i * angle, angle));
}
}
GraphicsPath getSegment(PointF center, float radius, float width,
float startAngle, float angle)
{
GraphicsPath gp = new GraphicsPath();
float radI = radius - width;
RectangleF OunterBounds =
new RectangleF(center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
RectangleF InnerBounds =
new RectangleF(center.X - radI, center.Y - radI, 2 * radI, 2 * radI);
gp.AddArc(OunterBounds, startAngle, angle);
gp.AddArc(InnerBounds, startAngle + angle, -angle);
gp.CloseFigure();
return gp;
}
private void pb_target_Paint(object sender, PaintEventArgs e)
{
for (int i = 0; i < segments.Count; i++)
{
GraphicsPath gp = segments[i];
e.Graphics.FillPath(Brushes.Gainsboro, gp);
e.Graphics.DrawPath(Pens.SlateBlue, gp);
}
}
最终版本中不需要上面的绘画代码,但是它将帮助您微调坐标,即getSegment
例程中的中心和尺寸.
You don't need the painting code above in the final version but it will help you to fine tune the coordinates, i.e. the center and the sizes in the getSegment
routine..
这里严格测试的是目标PB的MouseMove
事件:
Strictly for testing here is a MouseMove
event for the target PB:
private void pb_target_MouseMove(object sender, MouseEventArgs e)
{
for (int i = 0; i < segments.Count; i++)
{
GraphicsPath gp = segments[i];
if (gp.IsVisible(e.Location))
{
Text = "Inside segment #" + i;
break;
}
else Text = "Outside of the Circle";
}
}
请注意,片段是从左开始顺时针计数的..
Note the the segments count clockwise from the left..
这篇关于建议:在PictureBox之间拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!