0

我有一个 datagridview 显示车间中所有汽车的列表。在注册号的右侧,是几列阶段。每辆车的每个阶段的持续时间都已估算,接下来我需要显示实际花费的时间。理想情况下,这需要一个实时计时器。

数据网格截图

每个作业的每个阶段都可以处于活动状态、暂停或完成状态。

就数据库表而言,我有以下内容 -

工作详情

ID - PK Auto increment
JobID - Int (Joined to Jobs table)
PhaseID - String (joined to JobPhases table)
EstimatedTime - decimal
ActualTime decimal
Status int (EntryType - NotStarted, Active, Paused, Complete)

工作阶段

ID - PK String
Name - VarChar(150)

时间日志

ID int
JobID int
PhaseID string
UserID int
DateEntry datetime
EntryType int

通过条形码扫描用户 ID、作业编号、任务 ID 和操作(未开始、活动、暂停和完成)。然后,这会将作业设置为活动状态。

我可以通过将 JobDetail.ActualTime 添加到 TimeLog.LastEntry.DateEntry 来设置和获取所用时间。问题是我需要在每个单元格中将其显示为实时代码,或者至少大约 10 秒间隔刷新

我到目前为止的代码是 -

    private void tstbCommand_Leave(object sender, EventArgs e)
    {
            User u = User.FromID(Convert.ToInt32(tstbUser.Text.TrimStart('U')));
            Job j = Job.FromID(Convert.ToInt32(tstbJobNo.Text.TrimStart('E', 'N', 'K', 'J', 'C')));
            JobDetail jd = JobDetail.JobDetailFromJobIDAndPhaseID(j.ID, tstbTaskID.Text.TrimStart('E', 'N', 'K', 'J', 'C', 'D'));
            TimeLog log = new TimeLog();

            switch (tstbCommand.Text)
            {
                case "CMDACTIVE":
                    if (jd.Status == EntryType.Active)
                    {
                        //Alert already active
                        lstAlerts.Items.Add("The scanned job is already active.");
                    }
                    else
                    {
                        //Ok to update status to active
                        jd.Status = EntryType.Active;
                        log.EntryType = jd.Status;

                        JobPhaseTimer timer = new JobPhaseTimer();
                        timer.UID = jd.ID + "_" + jd.PhaseID;
                        timer.JobDetailID = jd.ID;
                        timer.JobID = j.ID;
                        timer.PhaseID = jd.PhaseID;
                        timer.StartTime = DateTime.Now;
                        timer.Stopwatch.Start();
                        timer.Start();
                        timers.Add(timer.UID, timer);

                        lstAlerts.Items.Add("The job " + jd.JobID + " has been set to active by " + u.FullName + ".");
                    }
                    break;
                case "CMDPAUSE":
                    if (jd.Status == EntryType.Paused)
                    {
                        lstAlerts.Items.Add("The scanned job is already paused.");
                    }
                    else
                    {
                        JobPhase phase = JobPhase.FromID(jd.PhaseID);
                        jd.Status = EntryType.Paused;
                        log.EntryType = jd.Status;

                        TimeLog lastEntry = TimeLog.GetLastTimeLogEntry(j.ID, jd.PhaseID);
                        lstAlerts.Items.Add(lastEntry.EntryType + ", " + lastEntry.DateEntry);

                        jd.ActualTime = Convert.ToDecimal(jd.ActualTime) + Convert.ToDecimal(DateTime.Now.Subtract(lastEntry.DateEntry).TotalHours);
                        lstAlerts.Items.Add("The job phase " + phase.Name + " for job " + jd.JobID + " has been paused by " + u.FullName + ".");
                    }
                    break;
                case "CMDCOMPLETE":
                    if (jd.Status == EntryType.Complete)
                    {
                        lstAlerts.Items.Add("The scanned job is already completed.");
                    }
                    else
                    {
                        jd.Status = EntryType.Complete;
                        log.EntryType = jd.Status;
                        lstAlerts.Items.Add("The job " + jd.JobID + " has been completed by " + u.FullName + ".");
                    }
                    break;
                case "CMDQC":
                    if (u.MergedRole.HasRight("workshop.QualityCheck"))
                    {
                        if (jd.Status == EntryType.QualityChecked)
                        {
                            lstAlerts.Items.Add("The scanned job has already been quality checked.");
                        }
                        else
                        {
                            jd.Status = EntryType.QualityChecked;
                            log.EntryType = jd.Status;
                            lstAlerts.Items.Add("The job " + jd.JobID + " has been quality checked by " + u.FullName + ".");
                        }
                    }
                    else
                    {
                        lstAlerts.Items.Add("You do not have sufficient rights to quality check.");
                    }
                    break;
            }

            log.JobID = j.ID;
            log.UserID = u.ID;
            log.PhaseID = jd.PhaseID;

            log.EntryType = jd.Status;
            jd.UpdateJobDetail(u.Username);
            log.AddNewTimeLog();

            tstbJobNo.Text = "";
            tstbUser.Text = "";
            tstbTaskID.Text = "";
            tstbCommand.Text = "";
}

为了将数据保留在 datagridview 上,目前我在计时器滴答声上调用 LoadData() -

void LoadData()
    {
        foreach (JobPhaseTimer timer in timers.Values)
        {
            JobDetail jd = JobDetail.JobDetailFromJobIDAndPhaseID(timer.JobID, timer.PhaseID);
            jd.ActualTime = jd.ActualTime + Convert.ToDecimal(timer.Stopwatch.ElapsedMilliseconds);
            jd.UpdateJobDetail("Test");
        }

        dt = JobManager.GetTodaysJobs();

        if (dataGridView1.InvokeRequired)
            dataGridView1.Invoke(new MethodInvoker(delegate
            {
                //access picturebox here#
                dt = JobManager.GetTodaysJobs();
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.DataSource = dt;
                dataGridView1.AutoResizeColumns();
            }));
        else
        {
            //access picturebox here
            dt = JobManager.GetTodaysJobs();
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.DataSource = dt;
            dataGridView1.AutoResizeColumns();
        }
    }

最后,我必须根据 EstimatedTime/ActualTime 格式化单元格颜色。如果 ActualTime (Live) 低于 EstimatedTime - 绿色。如果 ActualTime 大于 EstimatedTime - Red,如果 Actualime 接近(逻辑尚未确定),则显示黄色。

关于如何实现上述目标的任何想法/想法?我以前没有做过实时数据网格!

4

0 回答 0