如何在DataGridView中更新倒数计时器?

时间:2020-10-08 21:18:19

标签: c# winforms datagridview timer

我创建了一个可由用户填充的DataGridView(构建队列)。用户必须插入必须等待的时间[文本框H和M]。选择建筑物并将其添加到队列后,用户可以按开始[按钮启动/停止],并且倒计时仍一次最多可开始4建筑物[名为Builders的文本框]。

已将建筑物添加到队列中: First - Buildings in queue

按开始。 4倒计时正在运行。 5号正在等待。 CountDown of 4 timers

第一个计时器为零后,该计时器的行将被删除。该程序未使用正确的计时器。 (屏幕截图之间有些延迟。)第一行已重复。第一行计时器已停止工作。其他人仍在倒数。但是第五排消失了。 After first timer hits zero

我希望程序能够在四个倒计时中的一个结束时继续下一个建筑物倒计时。

public void TimerFirstRow_Tick(object sender, EventArgs e)
        {

            if (time0 > 0 && this.dataGridView1.Rows.Count > 0)
            {
                time0--;
                this.dataGridView1.Rows[0].Cells[2].Value = string.Format("00:{0}:{1}", time0 / 60, time0 % 60);
            }
            else
            {
                timer_0.Stop();

            }

我认为这是错误/错误,倒计时的位置被硬编码到Timer Tick事件代码中。

开始按钮代码:

 private void StartButton_Click(object sender, EventArgs e)
    {
        QueueMax = this.dataGridView1.Rows.Count;
        
        if (MaxBuild.Text == "")
        {
            label3.Text = "Fill MaxBuilders:";
        }
        else
        {
            MaxBuilder = int.Parse(MaxBuild.Text);
        }
        if (QueueMax >= MaxBuilder)
        {
            if (!timerB)
            {

                if (QueueMax > 0)
                {
                    if (QueueMax == 1)
                    {
                        string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
                        string[] xyList = xycoord.Split(':');
                        int x = int.Parse(xyList[0]);
                        int y = int.Parse(xyList[1]);
                        this.WindowState = FormWindowState.Minimized;
                        Thread.Sleep(500);
                        SendKeys.Send("%+{TAB}");
                        Klikken(x, y);
                        this.WindowState = FormWindowState.Normal;

                        
                        time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
                        timer_0 = new DispatcherTimer();
                        timer_0.Interval = new TimeSpan(0, 0, 1);
                        timer_0.Tick += TimerFirstRow_Tick;
                        timer_0.Start();
                        StartButton.Text = "Stop";
                        timerB = true;
                    }

                    else if (QueueMax == 2)
                    {
                        string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
                        string[] xyList = xycoord.Split(':');
                        int x = int.Parse(xyList[0]);
                        int y = int.Parse(xyList[1]);
                        this.WindowState = FormWindowState.Minimized;
                        Thread.Sleep(500);
                        SendKeys.Send("%+{TAB}");
                        Klikken(x, y);
                        string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
                        string[] xyList1 = xycoord.Split(':');
                        int x1 = int.Parse(xyList[0]);
                        int y1 = int.Parse(xyList[1]);
                        Klikken(x1, y1);
                        this.WindowState = FormWindowState.Normal;



                        time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
                        time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
                        timer_0 = new DispatcherTimer();
                        timer_1 = new DispatcherTimer();
                        timer_0.Interval = new TimeSpan(0, 0, 1);
                        timer_1.Interval = new TimeSpan(0, 0, 1);
                        timer_0.Tick += TimerFirstRow_Tick;
                        timer_1.Tick += timer2_Tick_1;
                        timer_0.Start();
                        timer_1.Start();
                        StartButton.Text = "Stop";
                        timerB = false;
                    }
                    else if (QueueMax == 3)
                    {
                        string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
                        string[] xyList = xycoord.Split(':');
                        int x = int.Parse(xyList[0]);
                        int y = int.Parse(xyList[1]);
                        this.WindowState = FormWindowState.Minimized;
                        Thread.Sleep(500);
                        SendKeys.Send("%+{TAB}");
                        Klikken(x, y);
                        string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
                        string[] xyList1 = xycoord.Split(':');
                        int x1 = int.Parse(xyList[0]);
                        int y1 = int.Parse(xyList[1]);
                        Klikken(x1, y1);

                        string xycoord2 = this.dataGridView1.Rows[2].Cells[3].Value.ToString();
                        string[] xyList2 = xycoord.Split(':');
                        int x2 = int.Parse(xyList[0]);
                        int y2 = int.Parse(xyList[1]);
                        Klikken(x1, y1);
                        this.WindowState = FormWindowState.Normal;

                        time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
                        time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
                        time2 = Convert.ToInt32(this.dataGridView1.Rows[2].Cells[2].Value) * 60;
                        timer_0 = new DispatcherTimer();
                        timer_1 = new DispatcherTimer();
                        timer_2 = new DispatcherTimer();
                        timer_0.Interval = new TimeSpan(0, 0, 1);
                        timer_1.Interval = new TimeSpan(0, 0, 1);
                        timer_2.Interval = new TimeSpan(0, 0, 1);
                        timer_0.Tick += TimerFirstRow_Tick;
                        timer_1.Tick += timer2_Tick_1;
                        timer_2.Tick += timer3_Tick;
                        timer_0.Start();
                        timer_1.Start();
                        timer_2.Start();
                        StartButton.Text = "Stop";
                        timerB = false;
                    }
                    else if (QueueMax >= 4)
                    {
                        string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
                        string[] xyList = xycoord.Split(':');
                        int x = int.Parse(xyList[0]);
                        int y = int.Parse(xyList[1]);
                        this.WindowState = FormWindowState.Minimized;
                        Klikken(x, y);


                        string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
                        string[] xyList1 = xycoord.Split(':');
                        int x1 = int.Parse(xyList[0]);
                        int y1 = int.Parse(xyList[1]);
                        Thread.Sleep(500);
                        SendKeys.Send("%+{TAB}");
                        Klikken(x1, y1);


                        string xycoord2 = this.dataGridView1.Rows[2].Cells[3].Value.ToString();
                        string[] xyList2 = xycoord.Split(':');
                        int x2 = int.Parse(xyList[0]);
                        int y2 = int.Parse(xyList[1]);
                        Klikken(x1, y1);



                        string xycoord3 = this.dataGridView1.Rows[3].Cells[3].Value.ToString();
                        string[] xyList3 = xycoord.Split(':');
                        int x3 = int.Parse(xyList[0]);
                        int y3 = int.Parse(xyList[1]);
                        Klikken(x1, y1);
                        this.WindowState = FormWindowState.Normal;

                        time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
                        time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
                        time2 = Convert.ToInt32(this.dataGridView1.Rows[2].Cells[2].Value) * 60;
                        time3 = Convert.ToInt32(this.dataGridView1.Rows[3].Cells[2].Value) * 60;
                        timer_0 = new DispatcherTimer();
                        timer_1 = new DispatcherTimer();
                        timer_2 = new DispatcherTimer();
                        timer_3 = new DispatcherTimer();
                        timer_0.Interval = new TimeSpan(0, 0, 1);
                        timer_1.Interval = new TimeSpan(0, 0, 1);
                        timer_2.Interval = new TimeSpan(0, 0, 1);
                        timer_3.Interval = new TimeSpan(0, 0, 1);
                        timer_0.Tick += TimerFirstRow_Tick;
                        timer_1.Tick += timer2_Tick_1;
                        timer_2.Tick += timer3_Tick;
                        timer_3.Tick += timer4_Tick;
                        timer_0.Start();
                        timer_1.Start();
                        timer_2.Start();
                        timer_3.Start();
                        StartButton.Text = "Stop";
                        timerB = false;
                    }
                }
            }
            else
            {
                if (timer_0.IsEnabled)
                {
                    timer_0.Stop();
                    timerB = false;
                    StartButton.Text = "Start";
                } else if (timer_1.IsEnabled)
                {
                    timer_0.Stop();
                    timer_1.Stop();
                    timerB = false;
                    StartButton.Text = "Start";
                } else if (timer_2.IsEnabled)
                {
                    timer_0.Stop();
                    timer_1.Stop();
                    timer_2.Stop();
                    timerB = false;
                    StartButton.Text = "Start";
                } else if (timer_3.IsEnabled)
                {
                    timer_0.Stop();
                    timer_1.Stop();
                    timer_2.Stop();
                    timer_3.Stop();
                    timerB = false;
                    StartButton.Text = "Start";

                }

            }
        }
    } //Start Timers

1 个答案:

答案 0 :(得分:1)

我建议使用单个计时器,然后从原始的Waiting Time中减去经过的时间。重要的代码在timer_Tick方法中:

public class BuildingForm : Form {

    DataGridView dgv = new DataGridView();
    DataTable table = new DataTable();

    Button btnRemoveUpgrade = new Button { Text = "Remove Upgrade" };
    Button btnAddBuilding = new Button { Text = "Add Building" };
    Button btnStart = new Button { Text = "Start" };
    Button btnUpgradeBuilding = new Button { Text = "Upgrade Building" };
    Label lbBuilders = new Label { Text = "Builders:", AutoSize = true, Anchor = AnchorStyles.Bottom | AnchorStyles.Left };
    Label lbWaitTime = new Label { Text = "Wait Time In:", AutoSize = true, Margin = new Padding(0, 20, 0, 0), Anchor = AnchorStyles.Bottom };
    Label lbHours = new Label { Text = "H:", AutoSize = true, Anchor = AnchorStyles.None };
    Label lbMinutes = new Label { Text = "M:", AutoSize = true, Anchor = AnchorStyles.None };
    NumericUpDown nudHours = new NumericUpDown { Minimum = 0, Maximum = 99, Value = 0, Increment = 1, AutoSize = true };
    NumericUpDown nudMinutes = new NumericUpDown { Minimum = 0, Maximum = 59, Value = 1, Increment = 1, AutoSize = true };
    NumericUpDown nudBuilders = new NumericUpDown { Minimum = 1, Maximum = 9999, Value = 4, Increment = 1, AutoSize = true };
    //---
    Timer timer = new Timer { Interval = 1000 };
    DateTime utcStartTime = DateTime.MinValue;
    DataColumn colBuilding;
    DataColumn colToLevel;
    DataColumn colWaitingTime;
    DataColumn colXY;
    List<Data> dataList = new List<Data>();

    public BuildingForm() : base() {
        this.Size = new Size(800, 600);
        this.StartPosition = FormStartPosition.CenterScreen;

        dgv.DataSource = table;
        dgv.Dock = DockStyle.Fill;
        dgv.AllowUserToAddRows = false;

        FlowLayoutPanel panel2 = new FlowLayoutPanel { FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight, WrapContents = false, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink };
        panel2.Controls.AddRange(new Control[] { lbHours, nudHours, lbMinutes, nudMinutes });

        TableLayoutPanel panel1 = new TableLayoutPanel { Dock = DockStyle.Fill, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink };       
        panel1.Controls.Add(btnRemoveUpgrade, 0, 0); panel1.Controls.Add(btnAddBuilding, 1, 0);
        panel1.Controls.Add(btnStart, 0, 1); panel1.Controls.Add(btnUpgradeBuilding, 1, 1);
        panel1.Controls.Add(lbBuilders, 0, 2); panel1.Controls.Add(lbWaitTime, 1, 2); panel1.Controls.Add(new Control(), 2, 2);
        panel1.Controls.Add(nudBuilders, 0, 3); panel1.Controls.Add(panel2, 1, 3);

        TableLayoutPanel panel = new TableLayoutPanel { Dock = DockStyle.Fill };
        panel.GrowStyle = TableLayoutPanelGrowStyle.AddColumns;
        panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1f));
        panel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        panel.Controls.Add(dgv, 0, 0);
        panel.Controls.Add(panel1, 1, 0);
        Controls.Add(panel);

        Size sz = btnUpgradeBuilding.PreferredSize;
        sz.Width += 20;
        sz.Height += 20;
        foreach (Control c in new Control[] { btnRemoveUpgrade, btnAddBuilding, btnStart, btnUpgradeBuilding }) {
            c.Size = sz;
        }

        colBuilding = table.Columns.Add("Building");
        colToLevel = table.Columns.Add("To Level", typeof(int));
        colWaitingTime = table.Columns.Add("Waiting Time:", typeof(TimeSpan));
        colXY = table.Columns.Add("X:Y");

        table.Rows.Add("Test", 11, TimeSpan.FromMinutes(1), "100:100");
        table.Rows.Add("Test", 11, TimeSpan.FromMinutes(10), "100:100");
        table.Rows.Add("Test", 11, TimeSpan.FromMinutes(20), "100:100");
        table.Rows.Add("Test", 11, TimeSpan.FromMinutes(30), "100:100");
        table.Rows.Add("Test", 11, TimeSpan.FromMinutes(90), "100:100");

        dgv.BindingContext = new System.Windows.Forms.BindingContext(); // forces dgv columns to be created
        dgv.Columns[colWaitingTime.Ordinal].DefaultCellStyle.Format = "hh':'mm':'ss";

        btnStart.Click += btnStart_Click;
        timer.Tick += timer_Tick;
    }

    private void timer_Tick(object sender, EventArgs e) {
        DateTime utcNow = DateTime.UtcNow;
        TimeSpan ellapsed = utcStartTime - utcNow;
        for (int i = dataList.Count - 1; i >= 0; i--) {
            Data d = dataList[i];
            TimeSpan ts = d.tsOrig.Add(ellapsed);
            if (ts.Ticks <= 0) {
                table.Rows.Remove(d.row);
                dataList.RemoveAt(i);
            }
            else {
                d.row[colWaitingTime] = ts;
            }
        }
        dgv.Invalidate();
    }

    private class Data {
        public DataRow row;
        public TimeSpan tsOrig;
    }

    void btnStart_Click(object sender, EventArgs e) {
        int numBuilders = (int) nudBuilders.Value;
        for (int i = 0; i < numBuilders && i < table.Rows.Count; i++) {
            Data d = new Data { row = table.Rows[i], tsOrig = (TimeSpan) table.Rows[i][colWaitingTime] };
            dataList.Add(d);
        }

        utcStartTime = DateTime.UtcNow;
        timer.Start();
        btnStart.Enabled = false;
    }

    protected override void Dispose(bool disposing) {
        base.Dispose(disposing);
        if (disposing)
            timer.Dispose();
    }
}