图形定时器控件不能正常工作

本文关键字:工作 常工作 定时器 控件 不能 图形 | 更新日期: 2023-09-27 18:11:50

这是我做的一个自定义控件,一个图形计时器,但是,它不能正常工作。随着剩余时间的减少,将填充一个饼状图来表示剩余时间的减少,但它以意想不到的角度减少(为了调试目的,将其输出到列表框)。我怎样才能使它正常工作?此外,我对制作自定义控件非常陌生(这是我的第一次),所以任何关于良好编码指南的指针,不应该做什么等,都会非常有帮助。

using System;
using System.Drawing;
using System.Windows.Forms;
namespace TestCustomControl
{
    class GraphicalTimer : Control
    {
        public Color Timer { get; set; }
        public Color TimerEmpty { get; set; }
        public Color BorderColor { get; set; }
        private Timer t;
        public int MaxTime { get; set; }
        private int timeElapsed = 0;
        public GraphicalTimer()
        {
            DoubleBuffered = true;
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            BackColor = Color.Transparent;
            t = new Timer();
            t.Interval = 1000;
            t.Tick += t_Tick;
        }
        public void Start()
        {
            t.Start();
        }
        public void Stop()
        {
            t.Stop();
        }
        public void Reset()
        {
            timeElapsed = 0;
            Invalidate();
        }
        void t_Tick(object sender, EventArgs e)
        {
            timeElapsed += 1;
            if (timeElapsed == MaxTime)
            {
                t.Dispose();
            }
            Invalidate();
        }
        private float getAngleFromTime()
        {
            if (timeElapsed == 0)
            {
                return 0;
            }
            else
            {
                MainWindow.lb.Items.Add((360 / (MaxTime / timeElapsed)).ToString());
                return (360 / (MaxTime / timeElapsed));
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            Rectangle rc = ClientRectangle;
            g.FillEllipse(new SolidBrush(Timer), rc);
            g.FillPie(new SolidBrush(TimerEmpty), rc, -90, getAngleFromTime());
            g.DrawEllipse(new Pen(BorderColor, 4), rc);
            Font font = new Font("Arial", (float)rc.Height * 0.4f, FontStyle.Bold, GraphicsUnit.Pixel);
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString((MaxTime - timeElapsed).ToString("D2"), font, new SolidBrush(Color.Black), new RectangleF((rc.Width - rc.Width / 2) / 2, (rc.Height - rc.Height / 2) / 2, rc.Width * 0.7f, rc.Height * 0.7f));
        }
    }
    class MainWindow : Form
    {
        GraphicalTimer gt;
        Button startButton;
        Button stopButton;
        Button resetButton;
        public static ListBox lb;
        public MainWindow()
        {
            this.Text = "Test Application";
            gt = new GraphicalTimer();
            gt.MaxTime = 20;
            gt.BorderColor = Color.BurlyWood;
            gt.Timer = Color.Aqua;
            gt.TimerEmpty = Color.White;
            gt.Top = 10;
            gt.Left = 10;
            gt.Width = 50;
            gt.Height = 50;
            this.Controls.Add(gt);
            startButton = new Button();
            startButton.Top = 70;
            startButton.Left = 30;
            startButton.AutoSize = true;
            startButton.Text = "Start Timer";
            startButton.Click += startButton_Click;
            this.Controls.Add(startButton);
            stopButton = new Button();
            stopButton.Top = 70;
            stopButton.Left = startButton.Right + 10;
            stopButton.AutoSize = true;
            stopButton.Text = "Stop Timer";
            stopButton.Click += stopButton_Click;
            this.Controls.Add(stopButton);
            resetButton = new Button();
            resetButton.Top = 70;
            resetButton.Left = stopButton.Right + 10;
            resetButton.AutoSize = true;
            resetButton.Text = "Reset Timer";
            resetButton.Click += resetButton_Click;
            this.Controls.Add(resetButton);
            lb = new ListBox();
            lb.Top = resetButton.Bottom + 10;
            lb.Left = 10;
            lb.Width = this.ClientSize.Width - 20;
            lb.Height = this.ClientSize.Height - lb.Top - 10;
            this.Controls.Add(lb);
        }
        void resetButton_Click(object sender, EventArgs e)
        {
            gt.Reset();
        }
        void stopButton_Click(object sender, EventArgs e)
        {
            gt.Stop();
        }
        void startButton_Click(object sender, EventArgs e)
        {
            gt.Start();
        }
    }
    class StartClass
    {
        static void Main()
        {
            MainWindow form = new MainWindow();
            Application.EnableVisualStyles();
            Application.Run(form);
        }
    }
}

图形定时器控件不能正常工作

你正在使用整数来计算角度,并且在某种程度上可能会导致相当多的抖动。

360 / (MaxTime / timeElapsed)先用整数法求temp = MaxTime / timeElapsed的值,然后360 / temp也用整数除法求值。

尝试使用浮点数进行计算,然后如果需要的话,将最终结果转换为整数值。即使写360 * timeElapsed / MaxTime可能会减少工件,因为您然后首先乘以360 * timeElapsed,这是准确的(除非timeElapsed非常大)。

计算AngleForTime的方法错误。只要用下面的代码替换你的方法,它就会完成你的工作。

private float getAngleFromTime()
        {
            if (timeElapsed == 0)
            {
                return 0;
            }
            else
            {
                MainWindow.lb.Items.Add((360*timeElapsed) / MaxTime ).ToString();
                return (360*timeElapsed) / MaxTime ;
            }
        }