9 Replies - 635 Views - Last Post: 23 October 2013 - 08:39 PM Rate Topic: -----

#1 Wnt2bsleepin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 04-July 13

Drawing in DataGridViewTextBoxCell

Posted 22 October 2013 - 03:51 PM

I inherited from the DataGridViewTextBoxCell class to make my own form. The goal of this form is to be able to have a rectangle be drawn when a user clicks on it to signify that something has happened and for subsequent rectangles to be drawn underneath that one triangle. I followed this guide on how to inherit from a form and create your own. When a user clicks on the cell, it generates another rectangle and adds it to a list. Then it invalidates the cell so it is redrawn and the rectangle gets drawn to the screen. Currently, they are not being drawn to the screen and I don't know why.

public partial class DataGridViewCalendarCell : DataGridViewTextBoxCell
    {
        List<Rectangle> boxes; //Gonna have a list of events instead of rectangles

        public DataGridViewCalendarCell()
        {
            InitializeComponent();
            boxes = new List<Rectangle>();
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds,Rectangle cellBounds,
            int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue,
            string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
            {
            // Call the base class method to paint the default cell appearance.
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
                value, formattedValue, errorText, cellStyle,
                advancedBorderStyle, paintParts);

            // Retrieve the client location of the mouse pointer.
            Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);

            // If the mouse pointer is over the current cell, draw a custom border.
            if (cellBounds.Contains(cursorPosition))
            {
            
                foreach (Rectangle rect in boxes)
                {
                    graphics.DrawRectangle(Pens.Red, rect);
                }
            }
        }

        protected override void onmouseenter(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }

        protected override void onmouseleave(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }

        protected override void onclick(DataGridViewCellEventArgs e)
        {
            base.onclick(e);
            //Go through the list and make a rectange right underneath the last one
            
            if (boxes.Count > 0)
            {
                Rectangle lastRect = boxes[boxes.Count - 1];
                Rectangle newRect = new Rectangle(1, lastRect.Y + lastRect.Height, lastRect.Width, 20);
                boxes.Add(newRect);
            }

            else
            {
                Rectangle newRect = new Rectangle(1, 50, 100, 20);
                boxes.Add(newRect);
            }

            this.DataGridView.InvalidateCell(this);
        }
    }
}



Is there a better way to go about doing this? Thank you for any help.

Is This A Good Question/Topic? 0
  • +

Replies To: Drawing in DataGridViewTextBoxCell

#2 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3488
  • View blog
  • Posts: 11,902
  • Joined: 12-December 12

Re: Drawing in DataGridViewTextBoxCell

Posted 22 October 2013 - 04:25 PM

I've only had a quick look (it's late..) but the first thing I would do would be to put a messagebox in here:

if (cellBounds.Contains(cursorPosition))
{

to see if this condition is met.
Was This Post Helpful? 0
  • +
  • -

#3 Wnt2bsleepin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 04-July 13

Re: Drawing in DataGridViewTextBoxCell

Posted 22 October 2013 - 04:48 PM

View Postandrewsw, on 22 October 2013 - 04:25 PM, said:

I've only had a quick look (it's late..) but the first thing I would do would be to put a messagebox in here:

if (cellBounds.Contains(cursorPosition))
{

to see if this condition is met.



It is indeed going through the list.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3576
  • View blog
  • Posts: 11,126
  • Joined: 05-May 12

Re: Drawing in DataGridViewTextBoxCell

Posted 22 October 2013 - 08:04 PM

Are the rectangles you are drawing within the clipBounds? If not, then all the drawing you are doing is worth nothing because it is outside the clipping area. The reason why the DataGridView has a clipping area for each cell is so that it has the opportunity to minimize the area that may need repainting.
Was This Post Helpful? 0
  • +
  • -

#5 Wnt2bsleepin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 04-July 13

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 10:00 AM

View PostSkydiver, on 22 October 2013 - 08:04 PM, said:

Are the rectangles you are drawing within the clipBounds? If not, then all the drawing you are doing is worth nothing because it is outside the clipping area. The reason why the DataGridView has a clipping area for each cell is so that it has the opportunity to minimize the area that may need repainting.


I don't think they are in the clipbounds of the cell. They are being drawn in the origin, which I assumed was the upper left corner. How do I get it to draw a rectangle inside of the clipping area?
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3576
  • View blog
  • Posts: 11,126
  • Joined: 05-May 12

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 12:55 PM

Drawing in the clipping area is relatively simple. Simple use the clipping area as your bounds.

On the flip side, expanding the clipping area to include your rectangles that you are added which are outside the current clipping area maybe a little bit harder. I've never had to do this before, but I would start looking at seeing if there is a way to invalidate particular areas of the DataGridView and ensure that area includes the rectangles.
Was This Post Helpful? 0
  • +
  • -

#7 Wnt2bsleepin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 04-July 13

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 02:00 PM

I actually wanted the triangle to be drawn in the clipping area of the cell. I just don't know how I can position it inside the cell easily.

I modified the code to something similar to what I want

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calendar
{
    public partial class DataGridViewCalendarCell : DataGridViewTextBoxCell
    {
        List<Rectangle> boxes; //Gonna have a list of events instead of rectangles
        int boxCount = 0;

        public DataGridViewCalendarCell()
        {
            InitializeComponent();
            boxes = new List<Rectangle>();
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds,Rectangle cellBounds,
            int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue,
            string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
            {
            // Call the base class method to paint the default cell appearance.
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
                value, formattedValue, errorText, cellStyle,
                advancedBorderStyle, paintParts);

            // Retrieve the client location of the mouse pointer.
            Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);

            // If the mouse pointer is over the current cell, draw a custom border.
            if (cellBounds.Contains(cursorPosition))
            {
             //Rectangle newRect = new Rectangle(cellBounds.X + 1,
             //   cellBounds.Y + 1, cellBounds.Width - 4,
             //   cellBounds.Height - 4);
                //Rectangle newRect = new Rectangle(cellBounds.X + 1,
                //    cellBounds.Y + 1, cellBounds.Width, 20);
                for (int i = 0; i <= boxCount; i++)
                {
                    Rectangle newRect = new Rectangle(cellBounds.X + 1,
                        cellBounds.Y + 1 * (boxCount * (cellBounds.Height - 100)), cellBounds.Width - 4, cellBounds.Height - 80);
                    graphics.DrawRectangle(Pens.Red, newRect);
                }
            }
        }

        protected override void onmouseenter(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }

        protected override void onmouseleave(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }


        protected override void OnDoubleClick(DataGridViewCellEventArgs e)
        {
            base.OnDoubleClick(e);
            boxCount++;
            this.DataGridView.InvalidateCell(this);
        }
    }
}



Currently, it makes rectangles and goes down the cell. Like so.

Posted Image


It works, but it disappears when I move out of the box. Should I store the rectangles in a data structure and iterate through them?
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3576
  • View blog
  • Posts: 11,126
  • Joined: 05-May 12

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 02:14 PM

If disappears when you leave the cell because your line 39 says that the rectangle drawing should only happen when the cursor is within the cell. So obviously you need to remove or modify that condition if you want the cell to be painted with the rectangle even without the cursor being in the cell.
Was This Post Helpful? 0
  • +
  • -

#9 Wnt2bsleepin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 04-July 13

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 03:39 PM

Removed that line, and added the ability to generate a box where the user clicks and it keeps adding rectangles to the cells. I hope the way I am doing this is a good way.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calendar
{
    public partial class DataGridViewCalendarCell : DataGridViewTextBoxCell
    {
        Rectangle[] rectangles; //Gonna have a list of events instead of rectangles
        int rectCount = 0;
        Point cursorPosition;

        public DataGridViewCalendarCell()
        {
            InitializeComponent();
            rectangles = new Rectangle[5];
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds,Rectangle cellBounds,
            int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue,
            string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
            {
            // Call the base class method to paint the default cell appearance.
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
                value, formattedValue, errorText, cellStyle,
                advancedBorderStyle, paintParts);

           
            for (int i = 0; i < rectCount; i++)
            {
                if (cellBounds.Contains(cursorPosition))
                {
                    rectangles[i].X = cellBounds.X + 1;
                    //rectangles[i].Y = cursorPosition.Y + 1;
                    rectangles[i].Width = cellBounds.Width - 4;
                    rectangles[i].Height = cellBounds.Height - 80;
                }
            }
            
            for (int i = 0; i < rectCount; i++)
            {
                graphics.DrawRectangle(Pens.Red, rectangles[i]);
            }
            
        }

        protected override void onmouseenter(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }

        protected override void onmouseleave(int rowIndex)
        {
            //this.DataGridView.InvalidateCell(this);
        }


        protected override void OnDoubleClick(DataGridViewCellEventArgs e)
        {
            base.OnDoubleClick(e);
            this.DataGridView.InvalidateCell(this);
            Rectangle rect = new Rectangle();

           
            cursorPosition = this.DataGridView.PointToClient(Cursor.Position);
            addRectangle(rect);

            
        }

        private void addRectangle(Rectangle rect)
        {
            rect.Y = cursorPosition.Y; 
            rectangles[rectCount] = rect;
            if (rectCount < 4)
                rectCount++;
            else
                rectCount = 0;

        }
    }
}



Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3576
  • View blog
  • Posts: 11,126
  • Joined: 05-May 12

Re: Drawing in DataGridViewTextBoxCell

Posted 23 October 2013 - 08:39 PM

Won't lines 36-45 effectively change the rectangles that you added as a result of lines 65-87? If so, so why not just compute the rectangles the right way on lines 65-87 and drop lines 36-45.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1