我已经包含了2张图片,因此您可以更轻松地理解我的问题, 我不能直接在这里链接它们,因为我是新成员,所以我把它们放在我的Dropbox公共文件夹中,
图片1:设计视图 https://www.dropbox.com/s/wca5gstd8kdsie7/designView.png?dl=0
在这里你可以看到左边的一个组面板, 嵌套了6个较小的盒子,它们都是" pictureBoxes",
然后在右边是一个较大的图片框,其中一个较小的嵌套在里面,
图片2应用程序正在运行 https://www.dropbox.com/s/u5bknooks17of1r/appView.png?dl=0
在这里你可以看到左边加载的图像(请忽略图像的失真,这是我将要修复的内容)
我需要做的是将一些图像(短语)从左侧拖入右侧的圆圈,在"段内#34;
然后我想要保存圆圈,将新图像拖到它上面(我会做一个drawToBitmap),我只是想知道对我来说最好的方法是什么?< / p>
一些建议请不胜感激,
我现在可以移动左边的图像,但只有很少量,因为它们目前仅限于在图片框内移动,
答案 0 :(得分:0)
您的问题包含三个任务:
Controls
(此处:PictureBoxes
)。以下是关于每项任务的一些提示:
Controls
,最好使用MouseDown
存储起点和MouseMove
事件来更新移动控件的Location
。在MouseUp
事件中,您可以完成操作:可能处理命中,重置控件,输出用户消息等。请注意,事件属于您要移动的每个控件,但如果您将它们映射到所有控件的相同三个事件,则可以使用sender
参数移动右Control
。比重复相同的代码n次要好得多..
(甚至可以编写一个可重用的函数makeMoveable(Control ctl)
来使任何Control
可移动;这可能涉及三个事件的三个lambda
表达式。)
另请注意,如果您的控件最初位于某个容器内,比如Panel
,则需要将Parent
更改为Form
,最好是BringtoFront()
;在这里,您还需要根据原始父项的偏移量调整位置,并且需要使用Rectangle
使它们移动到表单上的所有其他控件之上。
GraphicsPath
更复杂的形状。可以通过向Rectangles
添加简单的内容来构造复杂的形状。 Rectangle.Contains(Point)
似乎更容易进行点击测试,因为它们具有GraphicsPaths
功能。没有特殊原因,GraphicsPath.IsVisible(Point)
的相同功能名为GraphicsPaths
。
Graphics.SetClip(segment)
列表,您可以使用它来限制绘图,并在使用PictureBox
后将正确的图像直接绘制到圆圈上。为了让您使用细分,这里有一个函数可以创建一个细分并将其绘制到Paint
事件中的Arcs
pb_target中。请注意,两个Closing
的绘制方向相反,因此Path
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
您在最终版本中不需要上面的绘画代码,但它可以帮助您微调坐标,即MouseMove
例程中的中心和大小。
此处严格测试是针对目标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";
}
}
事件:
{{1}}
请注意,这些段从左侧顺时针计数..