C# 使用按钮在PictureBox上绘制一条线作为坐标
目前,我正在根据显示的图像制作一个房间/办公室搜索程序 我在程序上遇到了问题,我想在2D地图上显示一条线,按钮将用于连接线的每个坐标。但在搜索一个房间后,不会出现任何线条C# 使用按钮在PictureBox上绘制一条线作为坐标,c#,winforms,coordinates,picturebox,C#,Winforms,Coordinates,Picturebox,目前,我正在根据显示的图像制作一个房间/办公室搜索程序 我在程序上遇到了问题,我想在2D地图上显示一条线,按钮将用于连接线的每个坐标。但在搜索一个房间后,不会出现任何线条 private void button2_Click(object sender, EventArgs e) { System.Drawing.Pen myPen; myPen = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
private void button2_Click(object sender, EventArgs e)
{
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
System.Drawing.Graphics frmGraphics = pictureBox1.CreateGraphics();
if (textBox1.Text == "")
{
MessageBox.Show("Nothing to Search!", "", MessageBoxButtons.OK);
}
else
{
if (radioButton2.Checked == true)
{
if(textBox1.Text == "dental clinic")
{
frmGraphics.DrawLine(myPen, path1.Location.X, path1.Location.Y, path2.Location.X, path2.Location.Y);
Thread.Sleep(500);
frmGraphics.DrawLine(myPen, path2.Location.X, path2.Location.Y, path3.Location.X, path3.Location.Y);
Thread.Sleep(500);
frmGraphics.DrawLine(myPen, path3.Location.X, path3.Location.Y, path4.Location.X, path4.Location.Y);
lbres.Text = "Dental Clinic";
lbloc.Text = "OutPatient Department";
OPDView opdfrm = new OPDView();
dview = opdfrm;
}
else
{
MessageBox.Show("No Results Found!", "", MessageBoxButtons.OK);
}
myPen.Dispose();
frmGraphics.Dispose();
return;
}
}
我有4个按钮,a将其重命名为path1-path4,并希望将它们全部连接到线路上。关于这一点我需要一些帮助,谢谢。代码有更多问题,但我只在最后提示一下 你可能会犯的错误是没有得到正确的坐标
PictureBox
不是一个容器控件,因此无论您在顶部放置什么,它都是不坐在里面的。通过移动PB进行测试:按钮不会随之移动请注意,这不同于将按钮
放在面板
或分组框
上
有两种方法可以解决此问题:
- 您可以在代码或中创建
图片框的按钮
子项
- 您可以计算正确的位置
下面是如何制作PB的按钮子项:
path1.Parent = pictureBox1;
path2.Parent = pictureBox1;
path3.Parent = pictureBox1;
请注意,您现在必须采用移动按钮的代码
或者考虑到PB的位置,修正位置:
Point np1 = Point.Subtract(path1.Location, (Size)pictureBox1.Location);
Point np2 = Point.Subtract(path2.Location, (Size)pictureBox1.Location);
Point np3 = Point.Subtract(path3.Location, (Size)pictureBox1.Location);
frmGraphics.DrawLine(myPen, Point.Empty, np1 , np2);
...
另一个问题是,使用control.CreateGraphics
进行绘制的方法并不持久。事实上,它几乎总是错的!结果将在每次调整窗口大小时消失。。更好的方法是使用e.Graphics
参数绘制Picturebox.Paint
事件
我还想知道按钮的作用是什么?您可以创建一个列表
,也可以不使用它们进行绘制
另外,对动画使用Thread.Sleep(500)
将冻结UI线程。而是使用计时器
浏览点列表。如果你需要固定数量的动画制作方法,你可以创建一个字典来保存它们
更新
创建点列表很简单。在类级别声明它:
List<Point> way = new List<Point>();
同时创建一个计时器并设置其间隔。在其勾号事件中,向上移动指向当前段的指针,并调用Paint事件以使PictureBox无效:
void aTimer_Tick(object sender, EventArgs e)
{
point = Math.Min(point + 1, way.Count);
pictureBox1.Invalidate();
if (point >= way.Count) aTimer.Stop();
}
在PictureBox的绘制事件中,绘制从开始到当前索引的路径:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.DarkGoldenrod, 2.5f))
for (int i = 1; i < point; i++) e.Graphics.DrawLine(pen , way[i - 1], way[i]);
}
private void pictureBox1\u Paint(对象发送方,PaintEventArgs e)
{
使用(钢笔=新钢笔(Color.DarkGoldenrod,2.5f))
对于(inti=1;i
我遗漏了一些检查,您需要考虑一种存储或构建点列表的方法
您可能还希望通过绘制较小的线段来改进动画。为此,您可以添加更多点,但使用函数将更加灵活
int stepLen = 10; // draw 10 pixels on each tick
List<Point> SlowWay(List<Point> way)
{
List<Point> slow = new List<Point>();
for (int i = 1; i < way.Count; i++ )
{
int dx = way[i].X - way[i - 1].X;
int dy = way[i].Y - way[i - 1].Y;
float len = (float)Math.Sqrt(dx*dx+dy*dy);
int stepCount = (int)(len / stepLen);
float stepX = dx / stepCount;
float stepY = dy / stepCount;
slow.Add(way[i - 1]);
for (int s = 0; s < stepCount; s++)
slow.Add(new Point((int)(way[i - 1].X + s * stepX),
(int)(way[i - 1].Y + s * stepY)));
}
slow.Add(way[way.Count - 1]);
return slow;
}
int stepLen=10;//在每个刻度上画10个像素
列表慢行方式(列表方式)
{
List slow=新列表();
for(int i=1;i
代码有更多问题,但我只在最后提示一下
你可能会犯的错误是没有得到正确的坐标
PictureBox
不是一个容器控件,因此无论您在顶部放置什么,它都是不坐在里面的。通过移动PB进行测试:按钮不会随之移动请注意,这不同于将按钮
放在面板
或分组框
上
有两种方法可以解决此问题:
- 您可以在代码或中创建
图片框的按钮
子项
- 您可以计算正确的位置
下面是如何制作PB的按钮子项:
path1.Parent = pictureBox1;
path2.Parent = pictureBox1;
path3.Parent = pictureBox1;
请注意,您现在必须采用移动按钮的代码
或者考虑到PB的位置,修正位置:
Point np1 = Point.Subtract(path1.Location, (Size)pictureBox1.Location);
Point np2 = Point.Subtract(path2.Location, (Size)pictureBox1.Location);
Point np3 = Point.Subtract(path3.Location, (Size)pictureBox1.Location);
frmGraphics.DrawLine(myPen, Point.Empty, np1 , np2);
...
另一个问题是,使用control.CreateGraphics
进行绘制的方法并不持久。事实上,它几乎总是错的!结果将在每次调整窗口大小时消失。。更好的方法是使用e.Graphics
参数绘制Picturebox.Paint
事件
我还想知道按钮的作用是什么?您可以创建一个列表
,也可以不使用它们进行绘制
另外,对动画使用Thread.Sleep(500)
将冻结UI线程。而是使用计时器
浏览点列表。如果你需要固定数量的动画制作方法,你可以创建一个字典来保存它们
更新
创建点列表很简单。在类级别声明它:
List<Point> way = new List<Point>();
同时创建一个计时器并设置其间隔。在其勾号事件中,向上移动指向当前段的指针,并调用Paint事件以使PictureBox无效:
void aTimer_Tick(object sender, EventArgs e)
{
point = Math.Min(point + 1, way.Count);
pictureBox1.Invalidate();
if (point >= way.Count) aTimer.Stop();
}
在PictureBox的绘制事件中,绘制从开始到当前索引的路径:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.DarkGoldenrod, 2.5f))
for (int i = 1; i < point; i++) e.Graphics.DrawLine(pen , way[i - 1], way[i]);
}
private void pictureBox1\u Paint(对象发送方,PaintEventArgs e)
{
使用(钢笔=新钢笔(Color.DarkGoldenrod,2.5f))
对于(inti=1;i
我漏掉了几句话