使用按钮作为 PictureBox 上的坐标绘制一条线
Draw a line using buttons as a coordinates on a PictureBox
目前我正在根据显示的图像制作 Rooms/Office 的搜索程序。
我在程序上遇到问题,我想在 2D 地图上显示一条线,其中将使用按钮连接线的每个坐标。但是在搜索一个房间后,不会出现任何行。
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 个按钮,它们已重命名为路径 1 - 路径 4,并希望将它们全部连接起来。我需要一些帮助,谢谢。
代码有更多问题,但我只会在最后提示它们..
您可能遇到的错误是坐标不正确。
PictureBox
不是容器控件,所以无论你放在 top 上面什么都是 not sitting 里面它。通过移动 PB 进行测试:Buttons
不会随之移动 .. - 请注意,这不同于将 Button
放在 [=20= 上] 或 GroupBox
..
有两种修复方法:
- 您可以在代码中创建
PictureBox
的 Buttons
子代或
- 您可以计算出正确的位置。
以下是创建 PB 的 Button 子项的方法:
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
的绘制方式不持久。事实上,它几乎总是错的!结果将在每次 window 调整大小等时消失。更好的方法是使用 e.Graphics
参数在 Picturebox.Paint
事件中绘制。
我也想知道 Buttons
最初是做什么用的?您可以创建一个 List<Point>
并在没有它们的情况下进行绘制。
同时对动画使用 Thread.Sleep(500)
将冻结 UI 线程。而是使用 Timer
遍历点列表。如果你需要固定数量的动画方式,你可以创建一个 Dictionary<string, List<Point>>
来容纳它们..
更新
创建点列表很简单。在 class 级别声明它:
List<Point> way = new List<Point>();
知道数据后填写:
way.Add(new Point(100, 100));
way.Add(new Point(150, 100));
way.Add(new Point(150, 200));
way.Add(new Point(10, 200));
way.Add(new Point(10, 220));
way.Add(new Point(50, 220));
way.Add(new Point(50, 250));
同时创建一个计时器并设置它的间隔。在它的 Tick 事件中,您向上移动一个指向当前段的指针并调用 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 的 Paint 事件中绘制从开始到当前索引的路径:
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]);
}
我遗漏了一些检查,你会想出一种方法来存储或构建点列表..
您可能还想通过绘制更小的片段来改进动画效果。为此,您可以添加更多点,但使用函数会更灵活..:[=33=]
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;
}
目前我正在根据显示的图像制作 Rooms/Office 的搜索程序。
我在程序上遇到问题,我想在 2D 地图上显示一条线,其中将使用按钮连接线的每个坐标。但是在搜索一个房间后,不会出现任何行。
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 个按钮,它们已重命名为路径 1 - 路径 4,并希望将它们全部连接起来。我需要一些帮助,谢谢。
代码有更多问题,但我只会在最后提示它们..
您可能遇到的错误是坐标不正确。
PictureBox
不是容器控件,所以无论你放在 top 上面什么都是 not sitting 里面它。通过移动 PB 进行测试:Buttons
不会随之移动 .. - 请注意,这不同于将 Button
放在 [=20= 上] 或 GroupBox
..
有两种修复方法:
- 您可以在代码中创建
PictureBox
的Buttons
子代或 - 您可以计算出正确的位置。
以下是创建 PB 的 Button 子项的方法:
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
的绘制方式不持久。事实上,它几乎总是错的!结果将在每次 window 调整大小等时消失。更好的方法是使用 e.Graphics
参数在 Picturebox.Paint
事件中绘制。
我也想知道 Buttons
最初是做什么用的?您可以创建一个 List<Point>
并在没有它们的情况下进行绘制。
同时对动画使用 Thread.Sleep(500)
将冻结 UI 线程。而是使用 Timer
遍历点列表。如果你需要固定数量的动画方式,你可以创建一个 Dictionary<string, List<Point>>
来容纳它们..
更新
创建点列表很简单。在 class 级别声明它:
List<Point> way = new List<Point>();
知道数据后填写:
way.Add(new Point(100, 100));
way.Add(new Point(150, 100));
way.Add(new Point(150, 200));
way.Add(new Point(10, 200));
way.Add(new Point(10, 220));
way.Add(new Point(50, 220));
way.Add(new Point(50, 250));
同时创建一个计时器并设置它的间隔。在它的 Tick 事件中,您向上移动一个指向当前段的指针并调用 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 的 Paint 事件中绘制从开始到当前索引的路径:
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]);
}
我遗漏了一些检查,你会想出一种方法来存储或构建点列表..
您可能还想通过绘制更小的片段来改进动画效果。为此,您可以添加更多点,但使用函数会更灵活..:[=33=]
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;
}