C# 在visual studio 2013中从面板复制徒手绘制
我想在VisualStudio上徒手画一个表单(图片框),然后在另一个面板/图片框上复制相同的图形(我画的)。 它们也不应该是形成一条线的点,而是一条连续的线。请帮忙C# 在visual studio 2013中从面板复制徒手绘制,c#,winforms,panel,picturebox,C#,Winforms,Panel,Picturebox,我想在VisualStudio上徒手画一个表单(图片框),然后在另一个面板/图片框上复制相同的图形(我画的)。 它们也不应该是形成一条线的点,而是一条连续的线。请帮忙 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using Syst
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
Pen p_white;
bool draw = true;
private Graphics objgraphics;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen p_black = new Pen(new SolidBrush(Color.Black));
if (draw)
{
objgraphics = panel1.CreateGraphics();
}
}
/*private void panel1_MouseDown(object sender, MouseEventArgs e)
{
bool draw = true;
}*/
private void panel1_MouseMove_1(object sender, MouseEventArgs e)
{
Rectangle rEllipse = new Rectangle();
switch (e.Button)
{
case MouseButtons.Left:
rEllipse.X = e.X;
rEllipse.Y = e.Y;
rEllipse.Width = 5;
rEllipse.Height = 5;
objgraphics.DrawEllipse(System.Drawing.Pens.Black, rEllipse);
break;
case MouseButtons.Right:
rEllipse.X = e.X;
rEllipse.Y = e.Y;
rEllipse.Width = 3;
rEllipse.Height = 3;
objgraphics.DrawEllipse(System.Drawing.Pens.Black, rEllipse);
break;
default:
return;
}
}
/*private void panel1_MouseUp(object sender, MouseEventArgs e)
{
bool draw = false;
} */
private void form_Paint(object sender, EventArgs e)
{
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
Pen p_black = new Pen(new SolidBrush(Color.Black));
if (draw)
{ objgraphics = panel1.CreateGraphics();
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
看着你的代码,我恐怕不得不说:这是完全错误的 很抱歉这么直截了当,但您决不能使用control.CreateGraphics强>
- 首先要做的是扔掉
对象Graphics objgraphics
图形对象(几乎)总是错误的
相反,您必须使用从控件的Paint
事件中的e.Graphics
参数获得的参数
请注意,Graphics
不包含任何图形,它是一种用于在关联的位图
或控件表面上绘制的工具
- 接下来要做的是了解如何画手绘线。通常你可以看到你的代码;但它是无用的,只是一个例子,说明你在介绍中发现了多少愚蠢的事情。算了吧。它总是看起来像垃圾,因为圆圈从来都不光滑,一旦你把鼠标移动得更快,伪线就会完全散开
有一种很好的方法DrawCurve
可以画出平滑的线条。你给它一支笔和一组点
这就是我们将要使用的
让我们回到基础:如何创建图形?现在我们知道,您需要在Paint
事件中调用DrawCurve
:
e.Graphics.DrawCurve(somePen, somePointsArray);
这就引出了下一个问题:
- 什么是钢笔
- 有什么事吗,雷
还有一个隐藏的第三个问题:
- 画更多的线怎么样
第一个是简单的;创建一支笔划宽度为5.5像素的笔
,如下所示:
Pen somePen = new Pen(Color.Blue, 5.5f);
如果需要,也可以给它一个线条样式(破折号)
现在来看数组:在最简单的形式中,这也很容易
在MouseMove
事件中,您将当前位置存储在点列表中。首先,我们在类级别声明它:
List<Point> currentLine = new List<Point>();
注意最后一行:在控件上调用Invalidate
会触发系统来调用Paint
事件。它可能看起来很复杂,但这是唯一正确的方法,因为它保证了当某些其他原因需要时,同样的绘图也会发生
我们需要绘制,因为我们更改了应该绘制的数据。但是有许多外部原因,最著名的是最小化/最大化序列,它将清除图形并触发绘制事件。因此,我们需要配合windows绘制控件的方式!只有这样,图形才会持续显示
还要注意,我们不使用数组,因为我们不知道需要多少点。相反,我们使用列表
,然后将其强制转换为数组
让我们为我们的简单案例编写Paint
事件:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen somePen = new Pen(Color.Blue, 5.5f) )
if (currentLine.Count > 1) e.Graphics.DrawCurve(yourPen , currentLine.ToArray());
}
请注意,我已经使用
子句在中创建了笔
。这是一种既便宜又安全的方法,可确保正确处置笔
还要注意我们如何将列表
转换为数组
仅上述代码就可以工作,并允许您自由地画一条线
但是下一行呢?它不应该连接到第一个,所以我们不能只添加更多的点
因此,我们不仅需要一个点列表,还需要更多的,事实上,需要一个点列表:
List<List<Point>> curves = new List<List<Point>>();
请注意,我如何使用从列表
到列表
的强制转换来强制执行副本,否则将只分配引用,然后在下一行中清除
我们再次触发Paint
事件作为最后一件事
现在,我们应该更改Paint
事件以显示所有线条,包括当前正在绘制的线条和所有早期线条..:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen somePen = new Pen(Color.Blue, 5.5f) )
{
if (currentLine.Count > 1) e.Graphics.DrawCurve(somePen, currentLine.ToArray());
foreach (List<Point> lp in curves)
if (lp.Count > 1) e.Graphics.DrawCurve(somePen, lp.ToArray());
}
}
我注意到,您的原始代码允许您使用左键和右键使用两种不同的笔划宽度进行绘制。仅此一点就表明此代码不是很好。a)谁会想到这一点,b)只满足于两个笔划宽度
请阅读我在其中介绍的创建一个类,该类可以存储笔宽、颜色等,以便您可以在绘制的线条之间进行更改。这非常简单,只要您首先正确绘制。(即:将鼠标点存储在类级列表((或可能是列表)的mousemove中,并在面板绘制事件中绘制鼠标点。要复制鼠标点,您只需对面板2的绘制事件进行编码即可绘制相同的鼠标点。)-但由于您是新手,可能做得不对。你有代码给我们看吗?谢谢你。我愿意。这就是我用C#画画的方式。请现在检查代码。检查我写的答案。我有很多要学习和学习的东西,但它是值得的。谢谢TaW,我成功地完成了任务,你在详细的解释中帮了我很大的忙。现在我需要将这些图形保存在word文件中。我怎么能做到呢?不幸的是,我不做办公室自动化。你可以简单地使用创建包含图形的位图,但如何将其插入word文档我不知道。不过,应该有很多例子。。祝你好运
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (currentLine.Count > 1) curves.Add(currentLine.ToList()); // copy!!
currentLine.Clear();
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen somePen = new Pen(Color.Blue, 5.5f) )
{
if (currentLine.Count > 1) e.Graphics.DrawCurve(somePen, currentLine.ToArray());
foreach (List<Point> lp in curves)
if (lp.Count > 1) e.Graphics.DrawCurve(somePen, lp.ToArray());
}
}
curves.Clear(); currentLine .Clear(); panel1.Invalidate();