C# 如何在WinForms中绘制形状
我正试着编写类似绘画的程序。通过选择所需形状,单击picturebox并拖动鼠标以获得所需大小,可以绘制填充形状。但当我拖动时,会发生这种情况。当我使用C# 如何在WinForms中绘制形状,c#,winforms,C#,Winforms,我正试着编写类似绘画的程序。通过选择所需形状,单击picturebox并拖动鼠标以获得所需大小,可以绘制填充形状。但当我拖动时,会发生这种情况。当我使用refresh()时,先前绘制的形状会删除自身。我应该做什么来绘制填充形状 private void CizimPicture_MouseDown(object sender, MouseEventArgs e) { Cursor = Cursors.Cross; if (e.Button == Mouse
refresh()时代码>,先前绘制的形状会删除自身。我应该做什么来绘制填充形状
private void CizimPicture_MouseDown(object sender, MouseEventArgs e)
{
Cursor = Cursors.Cross;
if (e.Button == MouseButtons.Left)
{
cizim = true;
}
X1 = e.X;
Y1 = e.Y;
}
private void CizimPicture_MouseUp(object sender, MouseEventArgs e)
{
Cursor = Cursors.Default;
cizim = false;
}
private void CizimPicture_MouseMove(object sender, MouseEventArgs e)
{
if (!cizim) return;
if (cizim == true)
{
X = e.X;
Y = e.Y;
X2 = (e.X - X1);
Y2 = (Y1 - e.Y);
if (dikdörtgen == true)
{
resmim.FillRectangle(renk.Brush, X1, Y1, X2, -Y2);
}
if (elips == true)
{
resmim.FillEllipse(renk.Brush, X1, Y1, X2, -Y2);
}
}
}
我寻找既简单又有效的示例代码,但没有找到任何东西。您不需要屏幕外位图或CreateGraphics
,但您需要按照Eric的建议处理跟踪鼠标位置、在屏幕上绘制以及将绘制的形状添加到形状列表中。要处理交互式图形,需要在窗体处理程序中存储鼠标状态、初始单击位置和当前矩形:
bool mouseDown;
Point clickPos;
Rectangle rect;
然后,当用户单击时,记住初始位置:
private void MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
clickPos = e.Location;
rect = new Rectangle(clickPos, new Size(0, 0));
}
当用户向下拖动鼠标时,创建一个包含起始位置和当前位置的矩形:
private void MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
this.Invalidate(rect);
if (e.Location.X > clickPos.X && e.Location.Y > clickPos.Y)
{
rect = new Rectangle(clickPos.X, clickPos.Y, e.Location.X - clickPos.X, e.Location.Y - clickPos.Y);
}
else if (e.Location.X > clickPos.X && e.Location.Y < clickPos.Y)
{
rect = new Rectangle(clickPos.X, e.Location.Y, e.Location.X - clickPos.X, clickPos.Y - e.Location.Y);
}
else if (e.Location.X < clickPos.X && e.Location.Y < clickPos.Y)
{
rect = new Rectangle(e.Location.X, e.Location.Y, clickPos.X - e.Location.X, clickPos.Y - e.Location.Y);
}
else if (e.Location.X < clickPos.X && e.Location.Y > clickPos.Y)
{
rect = new Rectangle(e.Location.X, clickPos.Y, clickPos.X - e.Location.X, e.Location.Y - clickPos.Y);
}
this.Invalidate(rect);
}
}
Windows窗体中最重要的规则是:仅在绘制事件中绘制到屏幕。切勿在MouseMoved
事件中绘制:
private void Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.DarkGray, rect);
}
完成此操作后,创建一个表单列表
,并在MouseUp
事件中添加当前矩形,并在绘制
事件中绘制所有矩形。您可能还希望将图形剪裁到正在绘制的面板或窗口中。您还可以在MouseMoved
中进行一些优化,以仅使更改的屏幕区域无效,而不是使新旧矩形都无效。该程序正在执行它应该执行的操作;当你重画屏幕时,你必须告诉它,如果你想重画一些特定的东西,你应该重画什么。如果你不让它重画任何东西,那么结果就是什么都没有重画。如果你想在重画屏幕时重画一些东西,那么就编写这样做的代码。我认为你需要记住迄今为止已经绘制的所有形状,以便在调用refresh时可以重画它们,以及正在绘制的任何形状的位置。在紧要关头,你可以把你的形状绘制到位图上,然后直接显示出来,但这对你正在绘制的形状来说是不好的。Rup是正确的。通常,您要做的是记住位图中屏幕的先前状态,绘制该状态,然后在位图顶部绘制新形状。或者,您可以记住绘制的每个形状,然后在重新绘制屏幕时按正确的顺序重新绘制。我不知道如何将我的形状绘制成位图并再次显示。我试着用Paint handler而不是MouseMove来绘制我的形状,但没有成功,因为我无法获得坐标。事实上,我对编程相当陌生。如果我说的是不合理的话,对不起。请参阅和,以获取绘图更新/橡皮筋形状以及从形状数据列表中绘图的示例。。
private void Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.DarkGray, rect);
}