作者: wangwangwangcx
查看: 2558|回复: 4

[求助] 【求助】做了个程序,但是一直有点问题求大神指导

[复制链接]
wangwangwangcx 发表于 2018-7-6 16:38:55 | 显示全部楼层 |阅读模式
查看: 2558|回复: 4
10金钱
本帖最后由 wangwangwangcx 于 2018-7-6 16:40 编辑

新人小白,刚开始学习编写程序
想要实现的是做一个坐标轴,然后在这个坐标轴上会画一个图,然后还能够清除画的图保留坐标轴
原本是参考了一个鼠标移动画图的程序,然后自己改出来的
但是现在就是有个问题,画的图画好之后,不论是用clear还是refresh都会连原来画的坐标轴一起删了
如果再添加调用画坐标轴那么就会出现这样一次每次清除都会闪烁
想问怎么清除闪烁?
ps:我的程序中的坐标会一直变化的,这里没有表现出来,可以认为就是连续在图画上移动,我想程序表现出来的就他的运动轨迹
我做的程序效果:
可以看到我使用按钮3(清除,重画坐标轴的时候会闪烁一次)

【求助】做了个程序,但是一直有点问题求大神指导

【求助】做了个程序,但是一直有点问题求大神指导

代码如下:
控件添加了一个panel及三个button
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;

namespace DrawCurve
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            


        }
        private int MaxX = 200;//设置x的最大坐标
        private int MaxY = 230;//设置y的最大坐标
        private Graphics graXY;//创建图板
        private Graphics graMove;//创建图板
        private Pen Dpen = new Pen(Brushes.Black, 1);//设置画笔
        private Font Dfont = new Font("宋体", 8f);//设置字体格式
        private int xx = 0;//设置坐标
        private int yy = 0;//设置运动原坐标
        private Point MovePoint1;//动点1
        private Point MovePoint2;//动点2
        int a = 0;
       

        public void DrawXY()
        {
            Bitmap bt = new Bitmap(400, 400);
            graXY= Graphics.FromImage(bt);


            //画出x轴和y轴
            graXY = panel1.CreateGraphics();//在panel1上创建画图

                //MaxX = System.Convert.ToInt32(MaxX.Text);
                //绘制x轴
                Point px1 = new Point(5, MaxY);//坐标系x轴起点
                Point px2 = new Point(MaxX + 5, MaxY);//坐标系x轴终点
                graXY.DrawLine(new Pen(Brushes.Black, 1), px1, px2);//连接两点确定坐标轴x轴
                                                                    //绘制y轴
                Point py1 = new Point(5, MaxY);//坐标系y轴起点
                Point py2 = new Point(5, 0);//坐标系y轴终点
                graXY.DrawLine(Dpen, py1, py2);//连接两点确定坐标轴y轴

                //x轴的刻度线
                for (int i = 0; i <= 20; i++)//做循环,20等分x轴,标记每个等分线
                {
                    Point pxx1 = new Point(5 + MaxX * i / 20, MaxY);//刻度线起点
                    Point pxx2 = new Point(5 + MaxX * i / 20, MaxY - 5);//刻度线终点
                    string sx = null;//新建string类型 sy
                    sx = (MaxY * i / 20).ToString();//sy为每个刻度的值
                    graXY.DrawLine(Dpen, pxx1, pxx2);//画出刻度线
                    if (i % 4 == 0)
                    {
                        graXY.DrawString(sx, Dfont, Brushes.Black, new Point(MaxX * i / 20 + 5, MaxY));
                        //对部分等距标记坐标
                    }
                }
                graXY.DrawString("x轴", Dfont, Brushes.Black, new Point(MaxX + 5, MaxY + 10));//标记x轴

                //y轴分度线
                for (int i = 0; i <= 20; i++)//20等分y轴
                {
                    Point pyy1 = new Point(5, MaxY - MaxY * i / 20);//刻度线的起点
                    Point pyy2 = new Point(10, MaxY - MaxY * i / 20);//刻度线的终点
                    string sy = null;//新建sy存储当前位置刻度
                    sy = (MaxY * i / 20).ToString();
                    graXY.DrawLine(Dpen, pyy1, pyy2);//连接画出刻度线
                    if (i % 4 == 0)
                    {
                        graXY.DrawString(sy, Dfont, Brushes.Black, new PointF(5, MaxY - MaxY * i / 20));
                        //标记部分刻度
                    }
                }
                graXY.DrawString("y轴", Dfont, Brushes.Black, new Point(20, 0));//标记y轴
            this.CreateGraphics().DrawImage(bt, 0, 0);
        }
        public class PanelEx : Panel
        {
            public PanelEx()
            {
                SetStyle(ControlStyles.UserPaint, true);
                SetStyle(ControlStyles.AllPaintingInWmPaint, true);   //   禁止擦除背景. 
                SetStyle(ControlStyles.DoubleBuffer, true);
            }
        }
        private void OnTime(object sender,EventArgs e)
        {
            //graMove = Graphics.FromImage(bt);
            Pen LinePen = new Pen(Brushes.Red, 2);//运动轨迹线条格式
            this.MovePoint2.X = xx+5;//将当前坐标的x值赋值到点2中,并转化到当前坐标系坐标
            this.MovePoint2.Y = MaxY - yy;//将当前坐标的y值赋值到点2中,并转化到当前坐标系
            graMove.DrawLine(LinePen, MovePoint1, MovePoint2);//连接点1点2
            MovePoint1.X = this.MovePoint2.X;//将点2的值赋给点1
            MovePoint1.Y = this.MovePoint2.Y;
            this.Text="("+xx.ToString()+" , "+yy.ToString()+")";//当前窗体文本显示当前机械位置坐标
            if (a %2== 1)
            {//循环增加xy值  
            xx++;
            yy++;
            }
            else {
                timer1.Enabled = false;            
               
            }
            
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            this.UpdateStyles();
          
           //panel1.BackgroundImage = bmp;
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            DrawXY();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            
            
            DrawXY();//调用画xy
            
            //graMove.Clear(Color.White);
             //Refresh();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            MovePoint1.X = xx + 5;//将坐标点的x值转化到当前坐标系
            MovePoint1.Y = MaxY - yy;//将坐标点的y值转化到当前坐标系
            
            graMove = panel1.CreateGraphics();//在panel1上创建画图
            DrawXY();//调用画xy轴
            timer1.Interval = 50;//调整响应时间
            timer1.Enabled = true;//时钟可以触发
            timer1.Tick += new EventHandler(OnTime);//循环触发时钟,并保留循环结果
                                                    // DrawXY();
            a++;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //graMove.Clear(Color.White);
            Refresh();
            
            DrawXY();//调用画xy轴
           

        }
    }
}

最佳答案

查看完整内容

整个过程都不需要计时器,所有绘制操作都在OnPaint里完成。然后通过调用组件的Invalidate();函数来触发重绘。
回复 论坛版权

使用道具 举报

乔克斯 发表于 2018-7-6 16:38:56 | 显示全部楼层
整个过程都不需要计时器,所有绘制操作都在OnPaint里完成。然后通过调用组件的Invalidate();函数来触发重绘。
回复

使用道具 举报

 楼主| wangwangwangcx 发表于 2018-7-6 16:40:26 | 显示全部楼层
我去,,,,我本来想发10悬赏的,,,,,
回复

使用道具 举报

乔克斯 发表于 2018-7-9 02:22:12 | 显示全部楼层
如果需要自动画线的话就计时器,改组件里线的参数属性。然后通过调用组件的Invalidate();函数来触发重绘即可。
回复

使用道具 举报

 楼主| wangwangwangcx 发表于 2018-7-13 09:20:58 | 显示全部楼层
乔克斯 发表于 2018-7-9 02:22
如果需要自动画线的话就计时器,改组件里线的参数属性。然后通过调用组件的Invalidate();函数来触发重绘即 ...

好的,已经修改好了,另外加了块画图区域,到时候更新作图区域,这样不动坐标轴,避免更新的时候闪烁一次
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-3-29 00:12, Processed in 0.592178 second(s), 32 queries , Gzip On.

快速回复 返回顶部 返回列表