C# 油漆事件不过量
我有一个用C#编写的Windows窗体应用程序,带有绘图面板和一个用于绘制线条的按钮 单击按钮时,可以为2个随机点绘制一条线C# 油漆事件不过量,c#,winforms,panel,C#,Winforms,Panel,我有一个用C#编写的Windows窗体应用程序,带有绘图面板和一个用于绘制线条的按钮 单击按钮时,可以为2个随机点绘制一条线 Pen p = new Pen(Color.Black, 5); //point for start Point ps = new Point(); //point for end Point pe = new Point(); private void drawPanel_MouseDown(object sender, MouseEventArgs e) {
Pen p = new Pen(Color.Black, 5);
//point for start
Point ps = new Point();
//point for end
Point pe = new Point();
private void drawPanel_MouseDown(object sender, MouseEventArgs e)
{
ps.X = e.X;
ps.Y = e.Y;
pe = ps;
}
private void drawPanel_MouseMove(object sender, MouseEventArgs e)
{
// when button is clicked for drawing draw = true;
if (draw)
{
if (e.Button == MouseButtons.Left)
{
pe = new Point(e.X, e.Y);
}
}
}
private void drawPanel_MouseUp(object sender, MouseEventArgs e)
{
onMouseUpFlag = true;
}
private void drawPanel_Paint(object sender, PaintEventArgs e)
{
Graphics g = drawPanel.CreateGraphics();
if (onMouseUpFlag)
{
g.DrawLine(p, ps, pe);
g.Dispose();
}
}
该程序有一些缺陷:
- 当你画一条线时,只有当主窗口被移动时,它才会显示出来 某处(通常是我藏起来的时候)
- 它只能画一条线
Pen p = new Pen(Color.Black, 5);
Point ps = new Point();
Point pe = new Point();
List<Point> linesStart= new List<Point>();
List<Point> linesEnd= new List<Point>();
private void drawPanel_MouseDown(object sender, MouseEventArgs e)
{
ps.X = e.X;
ps.Y = e.Y;
linesStart.Add(ps);
pe = ps;
}
private void drawPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
pe = new Point(e.X, e.Y);
//adding end point .. actually adds a lot of points
linesEnd.Add(pe);
}
}
bool onMouseUpFlag = false;
private void drawPanel_MouseUp(object sender, MouseEventArgs e)
{
onMouseUpFlag = true;
drawPanel.Invalidate();
}
private void drawPanel_Paint(object sender, PaintEventArgs e)
{
if (onMouseUpFlag)
{
for (int i = 0; i < linesStart.Count; i++)
{
e.Graphics.DrawLine(p, linesStart[i], linesEnd[i]);
}
}
}
Pen p=新笔(颜色:黑色,5);
点ps=新点();
点pe=新点();
列表行开始=新建列表();
List linesEnd=新列表();
私有void drawPanel_MouseDown(对象发送器,MouseEventArgs e)
{
ps.X=e.X;
ps.Y=e.Y;
linesStart.Add(ps);
pe=ps;
}
私有void drawPanel_MouseMove(对象发送器,MouseEventArgs e)
{
if(e.Button==MouseButtons.Left)
{
pe=新点(e.X,e.Y);
//添加终点..实际上添加了很多点
linesEnd.Add(pe);
}
}
bool onMouseUpFlag=false;
私有void drawPanel_MouseUp(对象发送器,MouseEventArgs e)
{
onMouseUpFlag=true;
drawPanel.Invalidate();
}
私有void drawPanel_Paint(对象发送器、PaintEventArgs e)
{
如果(onMouseUpFlag)
{
对于(int i=0;i
现在我正在尝试修复多条线的抽绳。绘制事件可以绘制多条直线,但只有起点可以。不知何故,终点并不十分正确。在那里我可以精确地设置MouseMove事件的最后一个点 您必须调用面板上的Invalidate方法:
private void drawPanel_MouseUp(object sender, MouseEventArgs e)
{
onMouseUpFlag = true;
drawPanel.Invalidate();
}
另外,使用PaintEvent中的图形对象:
private void drawPanel_Paint(object sender, PaintEventArgs e)
{
if (onMouseUpFlag)
{
e.Graphics.DrawLine(p, ps, pe);
}
}
对于多条线,必须在集合对象中保留点
根据您更新的代码,下面是一个我认为您正在尝试做的工作示例:
private class Line {
public Point Starting { get; set; }
public Point Ending { get; set; }
public Line(Point starting, Point ending) {
this.Starting = starting;
this.Ending = ending;
}
}
List<Line> lines = new List<Line>();
private Point downPoint = Point.Empty;
private Point movePoint = Point.Empty;
private bool movingLine = false;
public Form1() {
InitializeComponent();
panel1.Paint += panel1_Paint;
panel1.MouseDown += panel1_MouseDown;
panel1.MouseMove += panel1_MouseMove;
panel1.MouseUp += panel1_MouseUp;
}
void panel1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
downPoint = e.Location;
}
}
void panel1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
movingLine = true;
movePoint = e.Location;
panel1.Invalidate();
}
}
void panel1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
movingLine = false;
lines.Add(new Line(downPoint, e.Location));
panel1.Invalidate();
}
}
void panel1_Paint(object sender, PaintEventArgs e) {
e.Graphics.Clear(Color.White);
foreach (Line l in lines) {
e.Graphics.DrawLine(Pens.Black, l.Starting, l.Ending);
}
if (movingLine) {
e.Graphics.DrawLine(Pens.Black, downPoint, movePoint);
}
}
私有类行{
公共点起点{get;set;}
公共点结尾{get;set;}
公共线路(起点、终点){
这个。开始=开始;
这个。结束=结束;
}
}
列表行=新列表();
专用点下降点=点。空;
私有点movePoint=Point.Empty;
私有布尔移动线=假;
公共表格1(){
初始化组件();
面板1.油漆+=面板1_油漆;
panel1.MouseDown+=panel1_MouseDown;
panel1.MouseMove+=panel1u MouseMove;
panel1.MouseUp+=panel1u MouseUp;
}
无效面板1_MouseDown(对象发送器,MouseEventArgs e){
if(e.Button==MouseButtons.Left){
下降点=e.位置;
}
}
无效面板1_MouseMove(对象发送器,MouseEventArgs e){
if(e.Button==MouseButtons.Left){
movingLine=true;
移动点=e.位置;
1.使无效();
}
}
无效面板1_MouseUp(对象发送器,MouseEventArgs e){
if(e.Button==MouseButtons.Left){
movingLine=false;
行。添加(新行(落点,e.位置));
1.使无效();
}
}
无效面板1_绘画(对象发送器,绘画事件参数e){
e、 图形。清晰(颜色。白色);
foreach(行中的行l){
e、 图形.抽绳(黑色笔,左起,左止);
}
如果(移动线路){
e、 图形.抽绳(钢笔.黑色,下降点,移动点);
}
}
使用可打开DoubleBuffer属性以避免闪烁。无论何时您想要重新绘制(在代码中),都应该调用panelinvalidate
drawPanel.Invalidate()
完成鼠标移动并释放按钮后
private void drawPanel_MouseUp(object sender, MouseEventArgs e)
{
onMouseUpFlag = true;
drawPanel.Invalidate();
}
最后,我建议您在drawPanel_Paint中使用此代码,而不是在您的drawPanel_Paint中使用此代码
. 您应该使用EventArgs提供的图形,而不是创建新图形
private void drawPanel_Paint(object sender, PaintEventArgs e)
{
if (onMouseUpFlag)
{
e.Graphics.DrawLine(p, ps, pe);
}
}
drawPanel.Invalidate()
即可重新绘制表单如果你像我一样懒惰的话,那就刷新一下。LarsTech,干得好!谢谢你的帮助!!我更新了我的答案。请尽量避免改变问题。如果您有更多问题,请随意将其作为单独的问题发布。