protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) { var centerY = CenterY(e.Graphics, e.CellBounds, out var width); if (e.RowIndex < 0) { var t = e.Value.ToString(); if (Running) { e.Graphics.FillRectangle(CursorBlink ? Brushes.DarkBlue : Brushes.DarkRed, e.CellBounds); var brush = CursorBlink ? Brushes.Cyan : Brushes.Yellow; e.Graphics.DrawString(t, Font, brush, e.CellBounds.X + 3, e.CellBounds.Y + centerY); } else { e.Graphics.FillRectangle(Brushes.Black, e.CellBounds); e.Graphics.DrawString(t, Font, Brushes.White, e.CellBounds.X + 3, e.CellBounds.Y + centerY); } } else { var job = (Job)Rows[e.RowIndex].Tag; if (job.Status == JobStatus.Running) { e.Graphics.FillRectangle(CursorBlink ? BackgroundFromStatus(job) : Brushes.Black, e.CellBounds); } else { e.Graphics.FillRectangle(BackgroundFromStatus(job), e.CellBounds); } switch (e.ColumnIndex) { case 0: { var x = e.CellBounds.X + e.CellBounds.Width - 2 - width; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(job.Number.ToString(), Font, ForgroundFromStatus(job), x, y); break; } case 1: { var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(job.Name, Font, ForgroundFromStatus(job), e.CellBounds.X + 3, y); break; } case 2: if (job.StartTime.HasValue) { var d = job.StartTime.Value.ToShortDateString(); var text = $"{d} {job.StartTime.Value.ToLongTimeString()}"; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(text, Font, ForgroundFromStatus(job), e.CellBounds.X + 3, y); } break; case 3: if (job.EndTime.HasValue) { var d = job.EndTime.Value.ToShortDateString(); var text = $"{d} {job.EndTime.Value.ToLongTimeString()}"; var x = e.CellBounds.X + 3; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(text, Font, ForgroundFromStatus(job), x, y); } else if (job.StartTime.HasValue) { var span = DateTime.Now.Subtract(job.StartTime.Value); var h = Math.Abs(span.Hours); var m = Math.Abs(span.Minutes); var s = Math.Abs(span.Seconds); var x = $"{h:00}:{m:00}:{s:00}"; var brush = CursorBlink ? Brushes.Black : Brushes.White; e.Graphics.DrawString(x, Font, brush, e.CellBounds.X + 3, e.CellBounds.Y + centerY); } break; case 4: if (job.StartTime.HasValue && job.EndTime.HasValue) { var span = job.EndTime.Value.Subtract(job.StartTime.Value); var h = Math.Abs(span.Hours); var m = Math.Abs(span.Minutes); var s = Math.Abs(span.Seconds); var x = $"{h:00}:{m:00}:{s:00}"; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(x, Font, ForgroundFromStatus(job), e.CellBounds.X + 3, y); } break; case 5: if (job.AllJobsStartTime.HasValue && job.EndTime.HasValue) { var span = job.EndTime.Value.Subtract(job.AllJobsStartTime.Value); var h = Math.Abs(span.Hours); var m = Math.Abs(span.Minutes); var s = Math.Abs(span.Seconds); var x = $"{h:00}:{m:00}:{s:00}"; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(x, Font, ForgroundFromStatus(job), e.CellBounds.X + 3, y); } break; case 6: { var x = e.CellBounds.X + 3; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(JobStatusHelper.GetStatusText(job.Status), Font, ForgroundFromStatus(job), x, y); } break; case 7: { var text = $"{(job.ExitCode == 0 ? "" : $"{job.ExitCode}: ")}{job.FailMessage}"; var x = e.CellBounds.X + 3; var y = e.CellBounds.Y + centerY; e.Graphics.DrawString(text, Font, ForgroundFromStatus(job), x, y); } break; } }