add custom DataGridViewColumn with label and button per cell

后端 未结 2 1412
终归单人心
终归单人心 2021-01-26 23:36

I want to add a custom DataGridViewColumn to my DataGridView. This column should create the following cell per row

At first I created

2条回答
  •  醉话见心
    2021-01-27 00:32

    I took this code and modified it to something a bit more dynamic this was a great start for me to build off of and I really appreciate this. I wanted to be able to select a folder with the button and open the folder by clicking the link.

    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Windows.Forms.VisualStyles;
    using System.IO;
    
    namespace Project
    {
    
    public class LinkButtonColumn : DataGridViewButtonColumn
    {
        private EventHandler buttonClickHandler;
        private EventHandler linkClickHandler;
        public LinkButtonColumn()
        {
            this.CellTemplate = new DataGridViewLinkButtonCell();
        }
    
        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                base.CellTemplate = value;
                DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
                if (cell != null)
                    cell.ButtonClickHandler = ButtonClickHandler;
                cell.LinkClickHandler = LinkClickHandler;
                
    
            }
        }
    
        public EventHandler LinkClickHandler
        {
            get
            {
                return linkClickHandler;
            }
            set
            {
                DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
                if (cell != null)
                {
                    if (value != null)
                        cell.LinkClickHandler += value;
                    else if (linkClickHandler != null)
                        cell.LinkClickHandler -= linkClickHandler;
                }
                linkClickHandler = value;
            }
        }
    
        public EventHandler ButtonClickHandler
        {
            get
            {
                return buttonClickHandler;
            }
            set
            {
                DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
                if (cell != null)
                {
                    if (value != null)
                        cell.ButtonClickHandler += value;
                    else if (buttonClickHandler != null)
                        cell.ButtonClickHandler -= buttonClickHandler;
                }
                buttonClickHandler = value;
            }
        }
    
    }
    internal sealed class DataGridViewLinkButtonColumn : DataGridViewColumn
    {
        private EventHandler buttonClickHandler;
        private EventHandler linkClickHandler;
        public string LabelText { get; set; }
        public string ButtonText { get; set; }
        public override object Clone()
        {
            var c = (DataGridViewLinkButtonColumn)base.Clone();
            c.LabelText = this.LabelText;
            c.ButtonText = this.ButtonText;
            return c;
        }
        public DataGridViewLinkButtonColumn() : base(new DataGridViewLinkButtonCell())
        {
        }
    
        public EventHandler LinkClickHandler
        {
            get
            {
                return linkClickHandler;
            }
            set
            {
                DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
                if (cell != null)
                {
                    if (value != null)
                        cell.LinkClickHandler += value;
                    else if (linkClickHandler != null)
                        cell.LinkClickHandler -= linkClickHandler;
                }
                linkClickHandler = value;
            }
        }
    
        public EventHandler ButtonClickHandler
        {
            get
            {
                return buttonClickHandler;
            }
            set
            {
                DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
                if (cell != null)
                {
                    if (value != null)
                        cell.ButtonClickHandler += value;
                    else if (buttonClickHandler != null)
                        cell.ButtonClickHandler -= buttonClickHandler;
                }
                buttonClickHandler = value;
            }
        }
    }
    
    public class DataGridViewLinkButtonCell : DataGridViewButtonCell
    {
        private Rectangle clickRectangleValue = new Rectangle();
        private string buttonPosion = "Middle";
        public EventHandler ButtonClickHandler { get; set; }
        public EventHandler LinkClickHandler { get; set; }
    
        public Rectangle ClickRectangle
        {
            get
            {
                Rectangle newRect = new Rectangle();
                switch (buttonPosion)
                {
                    case "Bottom":
                        newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y + (clickRectangleValue.Height - 20), 20, 20);
                        break;
                    case "Middle":
                        newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y + ((clickRectangleValue.Height - 20) / 2), 20, 20);
                        break;
                    case "Top":
                        newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y, 20, 20);                        
                        break;
                }
                
    
                return newRect;
            }
        }
    
        public override object Clone()
        {
            DataGridViewLinkButtonCell cell = base.Clone() as DataGridViewLinkButtonCell;
            if (cell != null)
            {
                cell.ButtonClickHandler = ButtonClickHandler;
                cell.LinkClickHandler = LinkClickHandler;
            }
            return cell;
        }
    
        protected override void Paint(Graphics graphics, Rectangle clipBounds,
            Rectangle cellBounds, int rowIndex,
            DataGridViewElementStates elementState,
            object value, object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
        {
            var g = this.DataGridView;
            var c = (DataGridViewLinkButtonColumn)this.OwningColumn;
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState,
                value, formattedValue, errorText, cellStyle, advancedBorderStyle,
                DataGridViewPaintParts.All &
                ~DataGridViewPaintParts.ContentBackground &
                ~DataGridViewPaintParts.ContentForeground);
            var r1 = g.GetCellDisplayRectangle(c.Index, rowIndex, false);
            
    
            
            Color forecolor = Color.Black;
            TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
            TextFormatFlags vertical = TextFormatFlags.VerticalCenter;
            switch (cellStyle.Alignment)
            {
                case DataGridViewContentAlignment.BottomCenter:
                    horizontal = TextFormatFlags.HorizontalCenter;
                    vertical = TextFormatFlags.Bottom;
                    break;
                case DataGridViewContentAlignment.BottomLeft:
                    horizontal = TextFormatFlags.Left;
                    vertical = TextFormatFlags.Bottom;
                    break;
                case DataGridViewContentAlignment.BottomRight:
                    horizontal = TextFormatFlags.Right;
                    vertical = TextFormatFlags.Bottom;
                    break;
                case DataGridViewContentAlignment.MiddleCenter:
                    horizontal = TextFormatFlags.HorizontalCenter;
                    vertical = TextFormatFlags.VerticalCenter;
                    break;
                case DataGridViewContentAlignment.MiddleLeft:
                    horizontal = TextFormatFlags.Left;
                    vertical = TextFormatFlags.VerticalCenter;
                    break;
                case DataGridViewContentAlignment.MiddleRight:
                    horizontal = TextFormatFlags.Right;
                    vertical = TextFormatFlags.VerticalCenter;
                    break;
                case DataGridViewContentAlignment.TopCenter:
                    horizontal = TextFormatFlags.HorizontalCenter;
                    vertical = TextFormatFlags.Top;
                    break;
                case DataGridViewContentAlignment.TopLeft:
                    horizontal = TextFormatFlags.Left;
                    vertical = TextFormatFlags.Top;
                    break;
                case DataGridViewContentAlignment.TopRight:
                    horizontal = TextFormatFlags.Right;
                    vertical = TextFormatFlags.Top;
                    break;
            }
    
    
            if (g.Rows[rowIndex].Cells[c.Index].Selected)
            {
                if (value != null)
                {
                    if (Directory.Exists(value.ToString()) || File.Exists(value.ToString()))
                    {
                        forecolor = Color.Red;
                        TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Underline),
                      r1, forecolor, Color.Empty,
                      horizontal |
                      vertical |
                      TextFormatFlags.TextBoxControl |
                      TextFormatFlags.WordBreak |
                      TextFormatFlags.EndEllipsis);
                    }
                    else
                    {
                        forecolor = Color.Blue;
                        TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Regular),
                      r1, Color.White, Color.Empty,
                      horizontal |
                      vertical |
                      TextFormatFlags.TextBoxControl |
                      TextFormatFlags.WordBreak |
                      TextFormatFlags.EndEllipsis);
                    }
                }
            }
            else
            {
                if (value != null)
                {
                    if (Directory.Exists(value.ToString()) || File.Exists(value.ToString()))
                    {
                        forecolor = Color.Blue;
                        TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Underline),
                      r1, forecolor, Color.Empty,
                      horizontal |
                      vertical |
                      TextFormatFlags.TextBoxControl |
                      TextFormatFlags.WordBreak |
                      TextFormatFlags.EndEllipsis);
                    }
                    else
                    {
                        forecolor = Color.Blue;
                        TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Regular),
                      r1, Color.Black, Color.Empty, 
                      horizontal |
                      vertical |
                      TextFormatFlags.TextBoxControl |
                      TextFormatFlags.WordBreak |
                      TextFormatFlags.EndEllipsis);
                    }
                }
            }
    
            
    
            Point cursorPosition = this.DataGridView.PointToClient(Cursor.Position);
    
            
            if (cellBounds.Contains(cursorPosition))
            {
                clickRectangleValue = cellBounds;
                Rectangle newRect = new Rectangle(cellBounds.X + 1,
                    cellBounds.Y + 1, cellBounds.Width - 4,
                    cellBounds.Height - 4);
                DataGridViewCellStyle style = cellStyle;
                style.Alignment = DataGridViewContentAlignment.MiddleCenter;
                base.Paint(graphics, clipBounds, ClickRectangle, rowIndex, elementState,
                value, c.ButtonText, errorText, style, advancedBorderStyle,
                DataGridViewPaintParts.All);
            }
            
        }
        protected override Rectangle GetContentBounds(Graphics graphics,
            DataGridViewCellStyle cellStyle, int rowIndex)
        {
            
            var r = base.GetContentBounds(graphics, cellStyle, rowIndex);
            switch (cellStyle.Alignment)
            {
                case DataGridViewContentAlignment.BottomCenter:
                    buttonPosion = "Bottom";
                    break;
                case DataGridViewContentAlignment.BottomLeft:
                    buttonPosion = "Bottom";
                    break;
                case DataGridViewContentAlignment.BottomRight:
                    buttonPosion = "Bottom";
                    break;
                case DataGridViewContentAlignment.MiddleCenter:
                    buttonPosion = "Middle";
                    break;
                case DataGridViewContentAlignment.MiddleLeft:
                    buttonPosion = "Middle";
                    break;
                case DataGridViewContentAlignment.MiddleRight:
                    buttonPosion = "Middle";
                    break;
                case DataGridViewContentAlignment.TopCenter:
                    buttonPosion = "Top";
                    break;
                case DataGridViewContentAlignment.TopLeft:
                    buttonPosion = "Top";
                    break;
                case DataGridViewContentAlignment.TopRight:
                    buttonPosion = "Top";
                    break;
            }
            clickRectangleValue = r;
            
            return new Rectangle(ClickRectangle.X, ClickRectangle.Y, ClickRectangle.Width, ClickRectangle.Height);
        }
            
    
        protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
        {
            int x = e.X;
            int y = e.Y;
    
            Point cursorPosition = this.DataGridView.PointToClient(Cursor.Position);
    
            var g = this.DataGridView;
            var r1 = GetContentBounds(e.RowIndex);
            var r2 = g.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
            r1.X = r1.X + r2.X;
            r1.Y = r1.Y + r2.Y;
            if (r1.Contains(cursorPosition))
            {                
                if (ButtonClickHandler != null)
                {
                    this.ButtonClickHandler.Invoke(this,e); 
                }
            }
            else
            {
                if (r2.Contains(cursorPosition))
                {
                    if (LinkClickHandler != null)
                    {
                        this.LinkClickHandler.Invoke(this, e);
                    }
                }
            }
            
        }
        
        protected override void OnMouseEnter(int rowIndex)
        {
            Cursor.Current = Cursors.Hand;
            this.DataGridView.Cursor = Cursor.Current;
            this.DataGridView.InvalidateCell(this);
            
        }
        
        protected override void OnMouseLeave(int rowIndex)
        {
            this.DataGridView.InvalidateCell(this);
            Cursor.Current = Cursors.Default;
            this.DataGridView.Cursor = Cursor.Current;
        }
    }
    }
    

    Then I pragmatically add the column to the grid.

    if (!Addendum_dataGridView.Columns.Contains("Folder_Location"))
        {
        DataGridViewLinkButtonColumn textButtonColumn = new DataGridViewLinkButtonColumn();
    
        textButtonColumn.ValueType = typeof(string);
        textButtonColumn.HeaderText = "Folder Location";
        textButtonColumn.ButtonText = "...";
        textButtonColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
        textButtonColumn.DefaultCellStyle.Padding = new Padding(1, 0, 0, 0);
        textButtonColumn.Width = 100;
        textButtonColumn.Name = "Folder_Location";
        textButtonColumn.DataPropertyName = "Folder_Location";           
        textButtonColumn.LinkClickHandler = (o, e) =>
         {
         if(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value != DBNull.Value)
         { 
             if (Directory.Exists(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString()) || File.Exists(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString()))
             {
             Process.Start(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString());
             }
         }
         };
        textButtonColumn.ButtonClickHandler = (o, e) =>
        {
        CommonOpenFileDialog cofd = new CommonOpenFileDialog();
        cofd.IsFolderPicker = true;
        cofd.Multiselect = false;
        cofd.Title = "Select Addendum Folder";
        if (Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value != DBNull.Value)
        {
            cofd.InitialDirectory = Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString();
        }
        else
        {
            cofd.InitialDirectory = Directory.GetParent(Directory.GetParent(SQL_Commands.Get_Data("select top 1 Quote_Location from [Index].[Estimates_Project_info] where Project_ID = " + P_ID).FirstOrDefault()).ToString()).ToString();
        }
        if (cofd.ShowDialog() == CommonFileDialogResult.Ok)
        {
            if (Addendum_dataGridView.Rows[e.RowIndex].IsNewRow)
            {
                int r = Addendum_dataGridView.NewRowIndex;
                DataTable dt = Addendum_dataGridView.DataSource as DataTable;
    
                DataRow row = dt.NewRow();
    
                row["Addendum_Number"] = Path.GetFileNameWithoutExtension(cofd.FileName.ToString());
                row["Folder_Location"] = cofd.FileName.ToString();
    
                dt.Rows.Add(row);
                dt = Addendum_dataGridView.DataSource as DataTable;
    
                bool blank = true;
                DataGridViewRow dgvr = Addendum_dataGridView.Rows[Addendum_dataGridView.Rows.Count - 2];
                for (int i = 0; i < Addendum_dataGridView.ColumnCount;i++)
                {
                    if (dgvr.Cells[i].Value != DBNull.Value)
                    {
                        blank = false;
                    }
            }
    
            if (blank)
            {
                Addendum_dataGridView.Rows.RemoveAt(Addendum_dataGridView.Rows.Count - 2);
            }
    
            insert_Addendum = true;
            Addendum_Data_Update(r);
        }
        else
        {
            Addendum_dataGridView["Folder_Location",e.RowIndex].Value = cofd.FileName.ToString();Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Selected = true;
            Addendum_Data_Update(e.RowIndex);
        }
        }
    
        };
    Addendum_dataGridView.Columns.Insert(Addendum_dataGridView.Columns.Count,textButtonColumn);
    } 
    

提交回复
热议问题