private bool DrawCandlestick(int offset, int top, AxisXUnit unit, Color eraseColor)
        {
            double[] dValues = null;
            bool     bCheck  = CheckBarsValue(offset, out dValues);

            if (bCheck)
            {
                int iOpen  = top + this.AxisY.ConvertValueToHeight(dValues[0]);
                int iHigh  = top + this.AxisY.ConvertValueToHeight(dValues[1]);
                int iLow   = top + this.AxisY.ConvertValueToHeight(dValues[2]);
                int iClose = top + this.AxisY.ConvertValueToHeight(dValues[3]);

                if (eraseColor != Color.Empty)
                {
                    __cGDI.FillRectangle(eraseColor, unit.LeftPoint + 1, iHigh, (unit.RightPoint - unit.LeftPoint) - 2, iLow - iHigh + 1);
                }

                bool   bOpenH  = iOpen < iClose;
                Color  cColor  = (bOpenH) ? this.ChartSetting.PenStyles[1].Color : this.ChartSetting.PenStyles[0].Color;
                IntPtr cOldPtr = __cGDI.SelectPen(this.ChartSetting.PenStyles[2]);

                __cGDI.DrawLine(unit.CenterPoint, iHigh, unit.CenterPoint, iLow);
                __cGDI.FillRectangle(cColor, unit.LeftPoint + 1, (bOpenH) ? iOpen : iClose, (unit.RightPoint - unit.LeftPoint) - 2, ((bOpenH) ? iClose - iOpen : iOpen - iClose) + 1);
                __cGDI.RemoveObject(__cGDI.SelectPen(cOldPtr));
            }
            return(bCheck);
        }
        private void DrawCellDrag(PaintEventArgs e)
        {
            if (DraggingCell != null)
            {
                var text    = "";
                int offsetX = 0;
                int offsetY = 0;
                if (QueryItemText != null)
                {
                    QueryItemText(DraggingCell.RowIndex.Value, DraggingCell.Column, out text, ref offsetX, ref offsetY);
                }

                Color bgColor = _backColor;
                if (QueryItemBkColor != null)
                {
                    QueryItemBkColor(DraggingCell.RowIndex.Value, DraggingCell.Column, ref bgColor);
                }

                int x1 = _currentX.Value - (DraggingCell.Column.Width.Value / 2);
                int y1 = _currentY.Value - (CellHeight / 2);
                int x2 = x1 + DraggingCell.Column.Width.Value;
                int y2 = y1 + CellHeight;


                Gdi.SetBrush(bgColor);
                Gdi.FillRectangle(x1, y1, x2 - x1, y2 - y1);
                Gdi.PrepDrawString(NormalFont, _foreColor);
                Gdi.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
            }
        }
        /// <summary>
        /// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices.
        /// </summary>
        private void DrawCellBG(Color color, Cell cell, List <RollColumn> visibleColumns)
        {
            int x, y, w, h;

            if (HorizontalOrientation)
            {
                x = RowsToPixels(cell.RowIndex.Value) + 1;
                w = CellWidth - 1;
                y = (CellHeight * visibleColumns.IndexOf(cell.Column)) + 1 - VBar.Value;                 // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
                h = CellHeight - 1;
                if (x < ColumnWidth)
                {
                    return;
                }
            }
            else
            {
                w = cell.Column.Width.Value - 1;
                x = cell.Column.Left.Value - HBar.Value + 1;
                y = RowsToPixels(cell.RowIndex.Value) + 1;                 // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
                h = CellHeight - 1;
                if (y < ColumnHeight)
                {
                    return;
                }
            }

            if (x > DrawWidth || y > DrawHeight)
            {
                return;
            }             // Don't draw if off screen.

            Gdi.SetBrush(color);
            Gdi.FillRectangle(x, y, w, h);
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            using (var LCK = Gdi.LockGraphics(e.Graphics))
            {
                Gdi.StartOffScreenBitmap(Width, Height);

                // White Background
                Gdi.SetBrush(Color.White);
                Gdi.SetSolidPen(Color.White);
                Gdi.FillRectangle(0, 0, Width, Height);

                // Lag frame calculations
                SetLagFramesArray();

                var visibleColumns = _columns.VisibleColumns.ToList();

                if (visibleColumns.Any())
                {
                    DrawColumnBg(e, visibleColumns);
                    DrawColumnText(e, visibleColumns);
                }

                //Background
                DrawBg(e, visibleColumns);

                //Foreground
                DrawData(e, visibleColumns);

                DrawColumnDrag(e);
                DrawCellDrag(e);

                Gdi.CopyToScreen();
                Gdi.EndOffScreenBitmap();
            }
        }
        private void DrawColumnBg(PaintEventArgs e, List <RollColumn> visibleColumns)
        {
            Gdi.SetBrush(SystemColors.ControlLight);
            Gdi.SetSolidPen(Color.Black);

            if (HorizontalOrientation)
            {
                Gdi.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
                Gdi.Line(0, 0, 0, visibleColumns.Count * CellHeight + 1);
                Gdi.Line(ColumnWidth, 0, ColumnWidth, visibleColumns.Count * CellHeight + 1);

                int start = -VBar.Value;
                foreach (var column in visibleColumns)
                {
                    Gdi.Line(1, start, ColumnWidth, start);
                    start += CellHeight;
                }

                if (visibleColumns.Any())
                {
                    Gdi.Line(1, start, ColumnWidth, start);
                }
            }
            else
            {
                int bottomEdge = RowsToPixels(0);

                // Gray column box and black line underneath
                Gdi.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
                Gdi.Line(0, 0, TotalColWidth.Value + 1, 0);
                Gdi.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);

                // Vertical black seperators
                for (int i = 0; i < visibleColumns.Count; i++)
                {
                    int pos = visibleColumns[i].Left.Value - HBar.Value;
                    Gdi.Line(pos, 0, pos, bottomEdge);
                }

                // Draw right most line
                if (visibleColumns.Any())
                {
                    int right = TotalColWidth.Value - HBar.Value;
                    Gdi.Line(right, 0, right, bottomEdge);
                }
            }

            // Emphasis
            foreach (var column in visibleColumns.Where(c => c.Emphasis))
            {
                Gdi.SetBrush(SystemColors.ActiveBorder);
                if (HorizontalOrientation)
                {
                    Gdi.FillRectangle(1, visibleColumns.IndexOf(column) * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
                }
                else
                {
                    Gdi.FillRectangle(column.Left.Value + 1 - HBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
                }
            }

            // If the user is hovering over a column
            if (IsHoveringOnColumnCell)
            {
                if (HorizontalOrientation)
                {
                    for (int i = 0; i < visibleColumns.Count; i++)
                    {
                        if (visibleColumns[i] != CurrentCell.Column)
                        {
                            continue;
                        }

                        if (CurrentCell.Column.Emphasis)
                        {
                            Gdi.SetBrush(Add(SystemColors.Highlight, 0x00222222));
                        }
                        else
                        {
                            Gdi.SetBrush(SystemColors.Highlight);
                        }

                        Gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
                    }
                }
                else
                {
                    //TODO multiple selected columns
                    for (int i = 0; i < visibleColumns.Count; i++)
                    {
                        if (visibleColumns[i] == CurrentCell.Column)
                        {
                            //Left of column is to the right of the viewable area or right of column is to the left of the viewable area
                            if (visibleColumns[i].Left.Value - HBar.Value > Width || visibleColumns[i].Right.Value - HBar.Value < 0)
                            {
                                continue;
                            }
                            int left  = visibleColumns[i].Left.Value - HBar.Value;
                            int width = visibleColumns[i].Right.Value - HBar.Value - left;

                            if (CurrentCell.Column.Emphasis)
                            {
                                Gdi.SetBrush(Add(SystemColors.Highlight, 0x00550000));
                            }
                            else
                            {
                                Gdi.SetBrush(SystemColors.Highlight);
                            }

                            Gdi.FillRectangle(left + 1, 1, width - 1, ColumnHeight - 1);
                        }
                    }
                }
            }
        }