Форма с панелью и коробками, нарисованными, пользователь нажимает на ящик, и на мгновение появляется надпись "box hit".
У меня есть рабочая версия кода, но я попытался переставить его, чтобы поэкспериментировать с его эффективностью, и я обнаружил, что в настоящее время я получаю это исключение.
Я не понимаю, почему это исключение происходит, и я хотел бы иметь возможность устранить его, но я не знаю, как это сделать. Я сузил его до какой линии. Но помимо этого я не знаю.
Ошибка возникает при щелчке по ящику. Таким образом, выполняется вырезка панели.
Все элементы управления, например. панель, метка, программно сгенерированы, так что, по всей видимости, возможно, что кто-нибудь сможет скопировать/вставить код, изменив имя класса и воспроизвести исключение, которое я получаю.
Я читал онлайн, что перо может генерировать исключение outofmemory, даже если оно действительно не из памяти, но оно просто бросает это исключение, хотя это все еще не говорит мне, почему и как его можно избежать, чтобы я мог понять, как писать код, где перо не выбрасывает это исключение.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication17
{
public partial class Form1 : Form
{
Label lbl1;
Panel panel;
Timer timer1;
Point[][] points = new Point[9][];
GraphicsPath[] gps = new GraphicsPath[9];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
panel = new Panel();
lbl1 = new Label();
timer1 = new Timer();
this.Controls.Add(panel);
Label alias = lbl1;
alias.Text = "box clicked";
alias.Visible = false;
panel.BackgroundImageLayout = ImageLayout.Stretch;
this.Height = 500; this.Width = 500;
panel.Controls.Add(lbl1);
panel.MouseDown += p_MouseDown;
timer1.Tick += timer1_Tick;
panel.BackColor = Color.White;
panel.Height = 400;
panel.Width = 400;
for (int i = 0; i < 9; i++) points[i] = new Point[4];
points[0][0] = new Point(19, 262);
points[0][1] = new Point(28, 257);
points[0][2] = new Point(27, 284);
points[0][3] = new Point(16, 285);
points[1][0] = new Point(52, 253);
points[1][1] = new Point(62, 250);
points[1][2] = new Point(61, 277);
points[1][3] = new Point(49, 278);
points[2][0] = new Point(87, 249);
points[2][1] = new Point(100, 248);
points[2][2] = new Point(99, 275);
points[2][3] = new Point(86, 274);
points[3][0] = new Point(126, 250);
points[3][1] = new Point(140, 252);
points[3][2] = new Point(139, 279);
points[3][3] = new Point(126, 277);
points[4][0] = new Point(164, 257);
points[4][1] = new Point(175, 260);
points[4][2] = new Point(175, 287);
points[4][3] = new Point(164, 284);
points[5][0] = new Point(197, 265);
points[5][1] = new Point(209, 269);
points[5][2] = new Point(209, 295);
points[5][3] = new Point(198, 292);
points[6][0] = new Point(228, 273);
points[6][1] = new Point(241, 275);
points[6][2] = new Point(240, 300);
points[6][3] = new Point(229, 300);
points[7][0] = new Point(262, 274);
points[7][1] = new Point(274, 273);
points[7][2] = new Point(275, 300);
points[7][3] = new Point(262, 301);
points[8][0] = new Point(297, 272);
points[8][1] = new Point(308, 268);
points[8][2] = new Point(311, 295);
points[8][3] = new Point(298, 296);
panel.Paint += thepanel_Paint;
// I can see that I can remove all the braces, but anyhow.
for (int i = 0; i < 9; i++)
{
using (gps[i] = new GraphicsPath())
using (Pen pen = new Pen(Color.Black, 1)) //this pen is not for drawing. but for the logic re graphicspath
{
gps[i].AddPolygon(points[i]);
}
}
}
void p_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mea = (MouseEventArgs)e;
//GraphicsPath[] gps = new GraphicsPath[9];
bool boxhit = false;
for (int i = 0; i < 9; i++)
{
using (Pen pen = new Pen(Color.Black, 1)) //this pen is not for drawing. but for the logic re graphicspath
{
bool cond1=false;
bool cond2=false;
cond1 = gps[i].IsOutlineVisible(new Point(mea.X, mea.Y), pen);
cond2 = gps[i].IsVisible(new Point(mea.X, mea.Y));
if (cond1 == true ||
cond2 == true)
{
boxhit = true;
lbl1.Visible = true;
timer1.Enabled = true;
}
}
} //for
// if (boxhit == false) MessageBox.Show("no box hit");
}
private void timer1_Tick(object sender, EventArgs e)
{
lbl1.Visible = false; timer1.Enabled = false;
}
private void thepanel_Paint(object sender, PaintEventArgs e)
{
GraphicsPath[] gps = new GraphicsPath[9];
Graphics gg = panel.CreateGraphics();
for (int i = 0; i < 9; i++)
using (gps[i] = new GraphicsPath())
{
gps[i].AddPolygon(points[i]);
gg.DrawPath(new Pen(Color.Blue, 1), gps[i]);
}
}
}
}
В качестве побочного примечания, вот код до перегруппировки, где он работает, он не генерирует исключение (хотя он, возможно, неэффективен в том, что каждый кусочек он добавляет многоугольники, чтобы определить, на что нажимается, когда на самом деле это только нужно один раз).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication15
{
public partial class Form1 : Form
{
Label lbl1;
Panel panel;
Timer timer1;
Point[][] points = new Point[9][];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
panel = new Panel();
lbl1 = new Label();
timer1 = new Timer();
this.Controls.Add(panel);
Label alias = lbl1;
alias.Text = "box clicked";
alias.Visible = false;
panel.BackgroundImageLayout = ImageLayout.Stretch;
this.Height = 500; this.Width = 500;
panel.Controls.Add(lbl1);
panel.MouseDown += p_MouseDown;
timer1.Tick += timer1_Tick;
panel.BackColor = Color.White;
panel.Height = 400;
panel.Width = 400;
for (int i = 0; i < 9; i++) points[i] = new Point[4];
points[0][0] = new Point(19, 262); //left top
points[0][1] = new Point(28, 257); //right top
points[0][2] = new Point(27, 284); //right bottom
points[0][3] = new Point(16, 285); //left bottom
points[1][0] = new Point(52, 253);
points[1][1] = new Point(62, 250);
points[1][3] = new Point(49, 278);
points[1][2] = new Point(61, 277);
points[2][0] = new Point(87, 249);
points[2][1] = new Point(100, 248);
points[2][3] = new Point(86, 274);
points[2][2] = new Point(99, 275);
points[3][0] = new Point(126, 250);
points[3][1] = new Point(140, 252);
points[3][3] = new Point(126, 277);
points[3][2] = new Point(139, 279);
points[4][0] = new Point(164, 257);
points[4][1] = new Point(175, 260);
points[4][3] = new Point(164, 284);
points[4][2] = new Point(175, 287);
points[5][0] = new Point(197, 265);
points[5][1] = new Point(209, 269);
points[5][3] = new Point(198, 292);
points[5][2] = new Point(209, 295);
points[6][0] = new Point(228, 273);
points[6][1] = new Point(241, 275);
points[6][3] = new Point(229, 300);
points[6][2] = new Point(240, 300);
points[7][0] = new Point(262, 274);
points[7][1] = new Point(274, 273);
points[7][3] = new Point(262, 301);
points[7][2] = new Point(275, 300);
points[8][0] = new Point(297, 272);
points[8][1] = new Point(308, 268);
points[8][3] = new Point(298, 296);
points[8][2] = new Point(311, 295);
panel.Paint += thepanel_Paint;
}
void p_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mea = (MouseEventArgs)e;
GraphicsPath[] gps = new GraphicsPath[9];
bool boxhit = false;
for (int i = 0; i < 9; i++)
{
using (gps[i] = new GraphicsPath())
using (Pen pen = new Pen(Color.Black,1)) //this pen is not for drawing. but for the logic re graphicspath
{
gps[i].AddPolygon(points[i]);
if (gps[i].IsOutlineVisible(new Point(mea.X, mea.Y), pen) == true || gps[i].IsVisible(new Point(mea.X, mea.Y)))
{
boxhit = true;
lbl1.Visible = true;
timer1.Enabled = true;
}
}
} //for
// if (boxhit == false) MessageBox.Show("no box hit");
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
lbl1.Visible = false; timer1.Enabled = false;
}
private void thepanel_Paint(object sender, PaintEventArgs e)
{
GraphicsPath[] gps = new GraphicsPath[9];
Graphics gg = panel.CreateGraphics();
for (int i = 0; i < 9; i++)
using (gps[i] = new GraphicsPath())
{
gps[i].AddPolygon(points[i]);
gg.DrawPath(new Pen(Color.Blue, 1), gps[i]);
}
}
}
}
Добавлен
В ответ на комментарий Ханса.
Я вижу, что я пропустил using
для этого графического объекта в процедуре рисования панели. Но если я добавлю его, значит, с этим кодом.
using(Graphics gg = panel.CreateGraphics())
for (int i = 0; i < 9; i++)
using (gps[i] = new GraphicsPath())
{
gps[i].AddPolygon(points[i]);
gg.DrawPath(new Pen(Color.Black, 1), gps[i]);
}
Я все еще получаю то же исключение в строке cond1 = gps[i].IsOutlineVisible(new Point(mea.X, mea.Y), pen);
в процедуре p_MouseDown
.
Добавлен дополнительный
ответ Q, но еще одна странная вещь. Я попытался создать простую программу, которая дает то же самое исключение, но программа не рушилась или выполнялась правильно, поэтому, возможно, возникла ли ошибка времени выполнения или нет что явно предикативно. Здесь я ожидал бы outofmemoryexception или, по крайней мере, два ящика сообщений, а не только один, и я не получаю исключения и только одно сообщение.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace blah
{
public partial class Form1 : Form
{
Pen p;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MessageBox.Show("sadf"); //displays
MessageBox.Show(p.Color.ToString()); // doesn't display a messagebox at all!
}
}
}