This is a migrated thread and some comments may be shown as answers.

Hit Test for CellClick event on GridView

5 Answers 379 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Francisco
Top achievements
Rank 1
Francisco asked on 16 Mar 2016, 09:31 PM

Hello,

  I have created a GridViewTextBoxColumn(), on _CellPaint() I am painting three images starting from the left to right.  I would like to detect a mouse click on the rectangle that corresponds to the image but I can't get the Cell.Size information on the CellClick() event.

I have tried creating a custom control that holds three buttons but the UI doesn't fit my needs.

In order to determine what was clicked on the cell, I need to know the click x/y and the current cell rectangle.

Thanks!

 

void grid_CellPaint(object sender, GridViewCellPaintEventArgs e)
        {
            GridDataCellElement dataCell = e.Cell as GridDataCellElement;
            if (dataCell != null && dataCell.ColumnInfo.FieldName == "ID")
            {
                Size cellSize = e.Cell.Size;
                Rectangle rct = new Rectangle(0, 0, cellSize.Height, cellSize.Height);
                //using (Pen p = new Pen(Color.Black))
               // {
                 
  //Flag
                    rct.Inflate(-2, -2);
                    e.Graphics.DrawImage(global::DIRC.UITools.Properties.Resources.Flag_red_icon16x16, rct);
           

                    //Information Icon
                    rct = new Rectangle(cellSize.Height, 0, cellSize.Height, cellSize.Height);
            
                    rct.Inflate(-2, -2);
                    e.Graphics.DrawImage(global::DIRC.UITools.Properties.Resources.information_icon_16x16, rct);

                    //Comment Icon
                    rct = new Rectangle(cellSize.Height * 2, 0, cellSize.Height, cellSize.Height);
                     
                    rct.Inflate(-2, -2);
                    e.Graphics.DrawImage(global::DIRC.UITools.Properties.Resources.comment_icon16x16, rct);
               // }
            }
        }

5 Answers, 1 is accepted

Sort by
0
Francisco
Top achievements
Rank 1
answered on 17 Mar 2016, 12:10 AM
I will take the approach of a custom GridDataCellElement with buttons.  Please disregard this post.
0
Hristo
Telerik team
answered on 17 Mar 2016, 03:32 PM
Hi Francisco,

Thank you for writing.

Indeed, creating a custom cell would be a better approach. Detailed information and examples are available here: http://docs.telerik.com/devtools/winforms/gridview/cells/creating-custom-cells.

I hope this helps. Please let me know if you need further assistance.

Regards,
Hristo Merdjanov
Telerik
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Francisco
Top achievements
Rank 1
answered on 17 Mar 2016, 03:52 PM

Hello Hristo,

  I looked at the example and what I came up is below.  Is there any way to improve it?

Thanks

- Francisco

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telerik.WinControls.Layouts;
using Telerik.WinControls.UI;
 
namespace ABC.UITools
{
    public class CustomGridDataCellElement : GridDataCellElement
    {
        private int _buttonCount = 3;
 
        public event EventHandler ButtonClick;
       
        public CustomGridDataCellElement(GridViewColumn column, GridRowElement row, int buttonCount)
            : base(column, row)
        {
            _buttonCount = buttonCount;
 
            for (int i = 0; i < _buttonCount; i++)
            {
                RadButtonElement radButtonElement = new RadButtonElement();
                radButtonElement.Name = "Button" + i.ToString("00");
                radButtonElement.Tag = i;
                radButtonElement.Click += new EventHandler(Button_Click);
                radButtonElement.StretchVertically = true;
                radButtonElement.StretchHorizontally = true;
                radButtonElement.ShowBorder = false;
                radButtonElement.ImageAlignment = ContentAlignment.TopLeft;
                this.Children.Add(radButtonElement);
            }
        }
 
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
        }
 
        private void Button_Click(object sender, EventArgs e)
        {
            this.OnButtonClick(sender, e);
        }
 
        public List<RadButtonElement> Buttons
        {
            get{
                return this.Children.Where(b => b is RadButtonElement).Cast<RadButtonElement>().ToList();
            }
        }
 
        public override bool IsEditable
        {
            get { return false; }
        }
 
        protected virtual void OnButtonClick(object sender, EventArgs e)
        {
            if (this.ButtonClick != null)
            {
                this.ButtonClick(sender, e);
            }
        }
 
        protected override void DisposeManagedResources()
        {
            foreach (var child in this.Children)
            {
                if (child is RadButtonElement)
                {
                    RadButtonElement btn = child as RadButtonElement;
                    btn.Click -= new EventHandler(Button_Click);
                }
            }
             base.DisposeManagedResources();
        }
 
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            RectangleF clientRect = this.GetClientRectangle(finalSize);
            float buttonWidth = clientRect.Size.Width / this.Children.Count;
            RectangleF buttonFinalRect = new RectangleF(clientRect.Location, new SizeF(buttonWidth, clientRect.Height));
 
            foreach (RadButtonElement button in this.Children)
            {
                button.Arrange(buttonFinalRect);
                buttonFinalRect = new RectangleF(new PointF(buttonFinalRect.X + buttonWidth, buttonFinalRect.Y), buttonFinalRect.Size);
            }
 
            return finalSize;
        }
 
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(GridDataCellElement);
            }
        }
 
        public override bool IsCompatible(GridViewColumn data, object context)
        {
            return data is TelerikCustomColumn && context is GridDataRowElement;
        }
    }
 
    public class TelerikCustomColumn : GridViewDataColumn
    {
        public TelerikCustomColumn(string fieldName)
            : base(fieldName)
        {
        }
 
        public override Type GetCellType(GridViewRowInfo row)
        {
            if (row is GridViewDataRowInfo)
            {
                return typeof(CustomGridDataCellElement);
            }
            return base.GetCellType(row);
        }
    }
}

The idea is to have different options of number of buttons depending on the grid that it is being used on.  So for a grid column that needs 3 buttons I would create it like this;

//When creating the grid template.  Width is determined based on the number of buttons to //be used * 20.  I will be using 16x16 bitmaps on the buttons.
  
grid.MasterTemplate.Columns.Add(new TelerikCustomColumn("Actions") { AllowReorder = false, AllowResize = false, Width = 60, HeaderText = "", AllowSort = false });     

0
Francisco
Top achievements
Rank 1
answered on 17 Mar 2016, 04:00 PM

Sorry I hit Post before finishing.

//On the CreateCell(object sender, GridViewCreateCellEventArgs e) event
//I do this.
 
TelerikCustomColumn dataColumn = e.Column as TelerikCustomColumn;
 
            if (e.Row is GridDataRowElement && dataColumn != null && e.Column.FieldName == "Actions")
            {
                //Here I pass the number of buttons
                CustomGridDataCellElement cell = new CustomGridDataCellElement(e.Column, e.Row, 3);
                e.CellElement = cell;
                //Load the button images.
                List<RadButtonElement> btns = cell.Buttons;
                foreach (var b in btns)
                {
                    if (b.Tag != null)
                    {
                        b.DisplayStyle = DisplayStyle.Image;
                        b.ImageAlignment = ContentAlignment.MiddleCenter;
                        if ((int)b.Tag == 0)
                        {
                            b.Image = global::ABC.UITools.Properties.Resources.img01;
                        }
                        else if ((int)b.Tag == 1)
                        {
                            b.Image = global::ABC.UITools.Properties.Resources.img02;
                        }
                        else if ((int)b.Tag == 2)
                        {
                            b.Image = global::ABC.UITools.Properties.img03;
                        }
                    }
                }
                cell.ButtonClick += new EventHandler(cell_ButtonClick);
            }

On the cell_ButtonClick..

private void cell_ButtonClick(object sender, EventArgs e)
        {
            RadButtonElement button = sender as RadButtonElement;
            CustomGridDataCellElement cell = button.Parent as CustomGridDataCellElement;
 
            if (button.Tag != null)
            {
                int idx = (int)button.Tag;
                System.Diagnostics.Debug.Write("\n cell.Button" + idx.ToString());
                switch (idx)
                {
                    case 0:
                        break;
                    case 1:
                        break;
                    case 2:
                        break;
                }
            }
        }

 

Thanks

Francisco

 

0
Hristo
Telerik team
answered on 18 Mar 2016, 08:59 AM
Hello Francisco,

Thank you for sharing your implementation.

The solution is valid and it follows the suggestions made in our Creating Custom Cells documentation article.

Please let me know if you need further assistance.

Regards,
Hristo Merdjanov
Telerik
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
GridView
Asked by
Francisco
Top achievements
Rank 1
Answers by
Francisco
Top achievements
Rank 1
Hristo
Telerik team
Share this question
or