Customizing the Windows Forms DataGrid

/CustomGridA/CustomDataGridreal/CS
============================
CustomColumnStyles.cs
using System;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace CustomDataGrid
{
   
    #region Formattable TextBox Column

    public class FormattableTextBoxColumn : DataGridTextBoxColumn
    {
        public event FormatCellEventHandler SetCellFormat;

        //used to fire an event to retrieve formatting info
        //and then draw the cell with this formatting info
        protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
        {
            DataGridFormatCellEventArgs e = null;

            bool callBaseClass = true;

            //fire the formatting event
            if(SetCellFormat != null)
            {
                int col = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
                e = new DataGridFormatCellEventArgs(rowNum, col, this.GetColumnValueAtRow(source, rowNum));
                SetCellFormat(this, e);
                if(e.BackBrush != null)
                    backBrush = e.BackBrush;

                //if these properties set, then must call drawstring
                if(e.ForeBrush != null || e.TextFont != null)
                {
                    if(e.ForeBrush == null)
                        e.ForeBrush = foreBrush;
                    if(e.TextFont == null)
                        e.TextFont = this.DataGridTableStyle.DataGrid.Font;
                    g.FillRectangle(backBrush, bounds);
                    Region saveRegion = g.Clip;
                    Rectangle rect = new Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height);
                    using(Region newRegion = new Region(rect))
                    {
                        g.Clip = newRegion;
                        int charWidth = (int) Math.Ceiling(g.MeasureString("c", e.TextFont, 20, StringFormat.GenericTypographic).Width);

                        string s = this.GetColumnValueAtRow(source, rowNum).ToString();
                        int maxChars = Math.Min(s.Length,  (bounds.Width / charWidth));

                        try
                        {
                            g.DrawString(s.Substring(0, maxChars), e.TextFont, e.ForeBrush, bounds.X, bounds.Y + 2);
                        }
                        catch(Exception ex)
                        {
                            Console.WriteLine(ex.Message.ToString());
                        } //empty catch
                        finally
                        {
                            g.Clip = saveRegion;
                        }
                    }
                    callBaseClass = false;
                }
                   
                if(!e.UseBaseClassDrawing)
                {
                    callBaseClass = false;
                }
            }
            if(callBaseClass)
                base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight);

            //clean up
            if(e != null)
            {
                if(e.BackBrushDispose)
                    e.BackBrush.Dispose();
                if(e.ForeBrushDispose)
                    e.ForeBrush.Dispose();
                if(e.TextFontDispose)
                    e.TextFont.Dispose();
            }
        }
    }

    #endregion

    #region Formattable Bool Column

    public class FormattableBooleanColumn : DataGridBoolColumn
    {
        public event FormatCellEventHandler SetCellFormat;

        //overridden to fire BoolChange event and Formatting event
        protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
        {
            int colNum = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
           
            //used to handle the boolchanging
            ManageBoolValueChanging(rowNum, colNum);
           
            //fire formatting event
            DataGridFormatCellEventArgs e = null;
            bool callBaseClass = true;
            if(SetCellFormat != null)
            {
                e = new DataGridFormatCellEventArgs(rowNum, colNum, this.GetColumnValueAtRow(source, rowNum));
                SetCellFormat(this, e);
                if(e.BackBrush != null)
                    backBrush = e.BackBrush;
                callBaseClass = e.UseBaseClassDrawing;
            }
            if(callBaseClass)
                base.Paint(g, bounds, source, rowNum, backBrush, new SolidBrush(Color.Red), alignToRight);

            //clean up
            if(e != null)
            {
                if(e.BackBrushDispose)
                    e.BackBrush.Dispose();
                if(e.ForeBrushDispose)
                    e.ForeBrush.Dispose();
                if(e.TextFontDispose)
                    e.TextFont.Dispose();
            }
        }

        //changed event
        public event BoolValueChangedEventHandler BoolValueChanged;
       
        bool saveValue = false;
        int saveRow = -1;
        bool lockValue = false;
        bool beingEdited = false;
        public const int VK_SPACE = 32 ;// 0x20

        //needed to get the space bar changing of the bool value
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern short GetKeyState(int nVirtKey);

        //set variables to start tracking bool changes
        protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
        {   
            lockValue = true;
            beingEdited = true;
            saveRow = rowNum;
            saveValue = (bool) base.GetColumnValueAtRow(source, rowNum);
            base.Edit(source, rowNum,  bounds, readOnly, instantText, cellIsVisible);
        }

        //turn off tracking bool changes
        protected override bool Commit(System.Windows.Forms.CurrencyManager dataSource, int rowNum)
        {
            lockValue = true;
            beingEdited = false;
            return base.Commit(dataSource, rowNum);
        }

        //fire the bool change event if the value changes
        private void ManageBoolValueChanging(int rowNum, int colNum)
        {
            Point mousePos = this.DataGridTableStyle.DataGrid.PointToClient(Control.MousePosition);
            DataGrid dg = this.DataGridTableStyle.DataGrid;
            bool isClickInCell = ((Control.MouseButtons == MouseButtons.Left) &&
                dg.GetCellBounds(dg.CurrentCell).Contains(mousePos) );

            bool changing = dg.Focused && ( isClickInCell
                || GetKeyState(VK_SPACE) < 0 ); // or spacebar
           
            if(!lockValue && beingEdited && changing && saveRow == rowNum)
            {
                saveValue = !saveValue;
                lockValue = false;

                //fire the event
                if(BoolValueChanged != null)
                {
                    BoolValueChangedEventArgs e = new BoolValueChangedEventArgs(rowNum, colNum, saveValue);
                    BoolValueChanged(this, e);
                }
            }
            if(saveRow == rowNum)
                lockValue = false;   
        }
    }

    #endregion

    #region CellFormatting Event

    public delegate void FormatCellEventHandler(object sender, DataGridFormatCellEventArgs e);

    public class DataGridFormatCellEventArgs : EventArgs
    {
        private int colNum;
        private int rowNum;
        private Font fontVal;
        private Brush backBrushVal;
        private Brush foreBrushVal;
        private bool fontDispose;
        private bool backBrushDispose;
        private bool foreBrushDispose;
        private bool useBaseClassDrawingVal;
        private object currentCellValue;

        public DataGridFormatCellEventArgs(int row, int col, object cellValue)
        {
            rowNum = row;
            colNum = col;
            fontVal = null;
            backBrushVal = null;
            foreBrushVal = null;
            fontDispose = false;
            backBrushDispose = false;
            foreBrushDispose = false;
            useBaseClassDrawingVal = true;
            currentCellValue = cellValue;
        }

   
        //column being painted
        public int Column
        {
            get{ return colNum;}
            set{ colNum = value;}
        }

        //row being painted
        public int Row
        {
            get{ return rowNum;}
            set{ rowNum = value;}
        }

        //font used for drawing the text
        public Font TextFont
        {
            get{ return fontVal;}
            set{ fontVal = value;}
        }

        //background brush
        public Brush BackBrush
        {
            get{ return backBrushVal;}
            set{ backBrushVal = value;}
        }

        //foreground brush
        public Brush ForeBrush
        {
            get{ return foreBrushVal;}
            set{ foreBrushVal = value;}
        }

        //set true if you want the Paint method to call Dispose on the font
        public bool TextFontDispose
        {
            get{ return fontDispose;}
            set{ fontDispose = value;}
        }
       
        //set true if you want the Paint method to call Dispose on the brush
        public bool BackBrushDispose
        {
            get{ return backBrushDispose;}
            set{ backBrushDispose = value;}
        }

        //set true if you want the Paint method to call Dispose on the brush
        public bool ForeBrushDispose
        {
            get{ return foreBrushDispose;}
            set{ foreBrushDispose = value;}
        }

        //set true if you want the Paint method to call base class
        public bool UseBaseClassDrawing
        {
            get{ return useBaseClassDrawingVal;}
            set{ useBaseClassDrawingVal = value;}
        }
       
        //contains the current cell value
        public object CurrentCellValue
        {
            get{ return currentCellValue;}
        }
    }
    #endregion

    #region BoolValueChanging Event
    public delegate void BoolValueChangedEventHandler(object sender, BoolValueChangedEventArgs e);

    public class BoolValueChangedEventArgs : EventArgs
    {
        private int columnVal;
        private int rowVal;
        private bool boolVal;

        public BoolValueChangedEventArgs(int row, int col, bool val)
        {
            rowVal = row;
            columnVal = col;
            boolVal = val;
        }
       
        //column to be painted
        public int Column
        {
            get{ return columnVal;}
            set{ columnVal = value;}
        }

        //row to be painted
        public int Row
        {
            get{ return rowVal;}
            set{ rowVal = value;}
        }

        //current value to be painted
        public bool BoolValue
        {
            get{return boolVal;}
        }
    }
    #endregion
}
===============
Form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace CustomDataGrid
{
    public class Form1 : System.Windows.Forms.Form
    {
        #region Fields
        //created by designer
        private System.Windows.Forms.DataGrid dataGrid1;
        private CustomDataGrid.DataSet1 dataSet11;
        private System.ComponentModel.Container components = null;

        // Used to refer to index specific columns in our grid.
        // Values set in CreateTheTable method.
        private int unitsInStockCol;
        private int unitsOnOrderCol;
        private int reorderLevelCol;
        private int checkCol;
        private int nameCol;

        // Cached GDI+ objects created in Form1_Load.
        // Used in the event handlers for the custom column styles events.
        private Brush disabledBackBrush;
        private Brush disabledTextBrush;
        private Brush alertBackBrush;
        private Font alertFont;
        private Brush alertTextBrush;
        private Font currentRowFont;
        private Brush currentRowBackBrush;

        // Grid tootips-fields used by the grid's mousemove events to manage
        //  row specific tips, initialized in Form_Load, used in dataGrid1_MouseMove.
        private int hitRow;
        private System.Windows.Forms.ToolTip toolTip1;
        #endregion

        #region Wizard Generated Code
        public Form1()
        {
            InitializeComponent();
        }

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                    //dispose of our cached graphics objects
                    if(disabledBackBrush != null)
                    {
                        disabledBackBrush.Dispose();
                        disabledTextBrush.Dispose();
                        alertBackBrush.Dispose();
                        alertFont.Dispose();
                        alertTextBrush.Dispose();
                        currentRowFont.Dispose();
                        currentRowBackBrush.Dispose();
                    }
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.dataGrid1 = new System.Windows.Forms.DataGrid();
            this.dataSet11 = new CustomDataGrid.DataSet1();
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataSet11)).BeginInit();
            this.SuspendLayout();
            //
            // dataGrid1
            //
            this.dataGrid1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                | System.Windows.Forms.AnchorStyles.Left)
                | System.Windows.Forms.AnchorStyles.Right);
            this.dataGrid1.CaptionText = "ReOrder Grid";
            this.dataGrid1.DataMember = "";
            this.dataGrid1.DataSource = this.dataSet11.Products;
            this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGrid1.Location = new System.Drawing.Point(24, 24);
            this.dataGrid1.Name = "dataGrid1";
            this.dataGrid1.Size = new System.Drawing.Size(440, 216);
            this.dataGrid1.TabIndex = 0;
            this.dataGrid1.Click += new System.EventHandler(this.dataGrid1_Click);
            this.dataGrid1.CurrentCellChanged += new System.EventHandler(this.dataGrid1_CurrentCellChanged);
            //
            // dataSet11
            //
            this.dataSet11.DataSetName = "DataSet1";
            this.dataSet11.Locale = new System.Globalization.CultureInfo("en-US");
            this.dataSet11.Namespace = "http://www.tempuri.org/DataSet1.xsd";
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(488, 261);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.dataGrid1});
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataSet11)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
        #endregion

        #region Initialization Code
        //Used to:
        //    Load the table.
        //    Set a tablestyle into the grid.
        //    Assign the grid's datasource.
        //    Create & cache some graphics objects.
        private void Form1_Load(object sender, System.EventArgs e)
        {
            //read the data
            this.dataSet11.ReadXml(GetPathTo("ProductsTable.XML"));

            //set the data source
            DataTable dt = this.dataSet11.Tables["Products"];
            this.dataGrid1.DataSource = dt;

            //add the tablestyle to the datagrid
            this.dataGrid1.TableStyles.Add(CreateTheTable());

            //create and cash some GDI+ objects that we are continually using
            //in our cell formatting.
            this.disabledBackBrush = new SolidBrush(SystemColors.InactiveCaptionText);
            this.disabledTextBrush = new SolidBrush(SystemColors.GrayText);
           
            this.alertBackBrush = new SolidBrush(SystemColors.HotTrack);
            this.alertFont = new Font(this.dataGrid1.Font.Name, this.dataGrid1.Font.Size, FontStyle.Bold);
            this.alertTextBrush = new SolidBrush(Color.White);
           
            this.currentRowFont = new Font(this.dataGrid1.Font.Name, this.dataGrid1.Font.Size, FontStyle.Bold);
            this.currentRowBackBrush = new SolidBrush(Color.FromArgb(255, 200, 200));

            //set up the grid tooltips
            this.hitRow = -1;
            this.toolTip1 = new ToolTip();
            this.toolTip1.InitialDelay = 300;
            this.dataGrid1.MouseMove += new MouseEventHandler(dataGrid1_MouseMove);
        }
   
        private DataGridTableStyle CreateTheTable()
        {
            //create an empty DataGridTableStyle & set mapping name to table
            DataGridTableStyle tableStyle = new DataGridTableStyle();
            tableStyle.MappingName = "Products";

            //now create custom DataGridColumnSyle for each col we want to
            //appear in the grid and in the order that we want to see them

            //Discontinued
            FormattableBooleanColumn discontinuedCol = new FormattableBooleanColumn();
            discontinuedCol.MappingName = "Discontinued";
            discontinuedCol.HeaderText = "";
            discontinuedCol.Width = 30;
            discontinuedCol.AllowNull = false; // turn off tristate
            this.checkCol = 0;

            discontinuedCol.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            discontinuedCol.BoolValueChanged += new BoolValueChangedEventHandler(BoolValueChanged);
            tableStyle.GridColumnStyles.Add(discontinuedCol);

            //ProductID
            FormattableTextBoxColumn column = new FormattableTextBoxColumn();
            column.MappingName = "ProductID";
            column.HeaderText = "ID";
            column.Width = 30;
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);

            //ProductName
            column = new FormattableTextBoxColumn();
            column.MappingName = "ProductName";
            column.HeaderText = "Name";
            column.Width = 140;
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);
            this.nameCol = 2;

            //   lets hide the next 2 columns by not adding a
            //   GridColumnStyle to the tableStyle

//            //SupplierID
//            column = new FormattableTextBoxColumn();
//            column.MappingName = "SupplierID";
//            column.HeaderText = "SupplierID";
//            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
//            tableStyle.GridColumnStyles.Add(column);

//            //CategoryID
//            column = new FormattableTextBoxColumn();
//            column.MappingName = "CategoryID";
//            column.HeaderText = "CategoryID";
//            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
//            tableStyle.GridColumnStyles.Add(column);

            //QuantityPerUnit
            column = new FormattableTextBoxColumn();
            column.MappingName = "QuantityPerUnit";
            column.HeaderText = "QuantityPerUnit";
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);

            //UnitPrice
            column = new FormattableTextBoxColumn();
            column.MappingName = "UnitPrice";
            column.HeaderText = "UnitPrice";
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);

            //UnitsInStock
            column = new FormattableTextBoxColumn();
            column.MappingName = "UnitsInStock";
            column.HeaderText = "UnitsInStock";
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);
            this.unitsInStockCol = 5;

            //UnitsOnOrder
            column = new FormattableTextBoxColumn();
            column.MappingName = "UnitsOnOrder";
            column.HeaderText = "UnitsOnOrder";
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);
            this.unitsOnOrderCol = 6;

            //ReorderLevel
            column = new FormattableTextBoxColumn();
            column.MappingName = "ReorderLevel";
            column.HeaderText = "ReorderLevel";
            column.SetCellFormat += new FormatCellEventHandler(SetCellFormat);
            tableStyle.GridColumnStyles.Add(column);
            this.reorderLevelCol = 7;
           
            return tableStyle;
        }
       

        //look back up in the project path for file...
        private string GetPathTo(string name)
        {
            for(int i = 0; i < 3; ++i)
            {
                if(File.Exists(name))
                    break;
                name = @"../" + name;
            }
            return name;
        }


        #endregion

        #region Custom ColumnStyle Events

        // Provides the format for the given cell.
        private void SetCellFormat(object sender, DataGridFormatCellEventArgs e)
        {
            //conditionally set properties in e depending upon e.Row and e.Col
            bool discontinued = (bool) ((e.Column != 0) ? this.dataGrid1[e.Row, 0] : e.CurrentCellValue);
            //check is discontinued
            if(e.Column > 0 && (bool)(this.dataGrid1[e.Row, 0]))//discontinued)
            {
                e.BackBrush = this.disabledBackBrush;
                e.ForeBrush = this.disabledTextBrush;
            }
            else if(e.Column > 0 && e.Row == this.dataGrid1.CurrentRowIndex)//discontinued)
            {
                e.BackBrush = this.currentRowBackBrush;
                e.TextFont = this.currentRowFont;
            }
            else if(NeedToReorder(e.Row))
            {
                e.TextFont = this.alertFont;
                e.ForeBrush = this.alertTextBrush;
                e.BackBrush = this.alertBackBrush;
            }
        }

        // Handles the changing of a boolvalue:
        //        Forces the value committed and then redraws the row.
        //        The value is committed so we can test it in our drawing
        //                code by just accessing the DataGridValue.
        private void BoolValueChanged(object sender, BoolValueChangedEventArgs e)
        {
            this.dataGrid1.EndEdit(this.dataGrid1.TableStyles[0].GridColumnStyles["Discontinued"],e.Row, false);
            RefreshRow(e.Row);
            this.dataGrid1.BeginEdit(this.dataGrid1.TableStyles[0].GridColumnStyles["Discontinued"],e.Row);
        }
        #endregion

        #region ToolTip Implementation

        // Checks mouse position to see if it is over a discontinued row,
        //        or reorder row. If so, set the tiptext and reset the tooltip.
        private void dataGrid1_MouseMove(object sender, MouseEventArgs e)
        {
            DataGrid.HitTestInfo hti = this.dataGrid1.HitTest(new Point(e.X, e.Y));
            BindingManagerBase bmb = this.BindingContext[this.dataGrid1.DataSource, this.dataGrid1.DataMember];
            if(hti.Row < bmb.Count && hti.Type == DataGrid.HitTestType.Cell
                &&  hti.Row != hitRow  )
            {   
                if(this.toolTip1 != null && this.toolTip1.Active)
                    this.toolTip1.Active = false; //turn it off

                string tipText = "";
                if((bool)this.dataGrid1[hti.Row, checkCol])
                    tipText = this.dataGrid1[hti.Row, nameCol].ToString() + " discontinued";
                else if    (this.NeedToReorder(hti.Row))
                {
                    tipText = this.dataGrid1[hti.Row, nameCol].ToString() + " order NOW";
                }
                if(tipText != "")
                {
                    //new hit row
                    hitRow = hti.Row;
                   
                    this.toolTip1.SetToolTip(this.dataGrid1, tipText);
                    this.toolTip1.Active = true; //make it active so it can show itself
                }
                else
                hitRow = -1;
            }
        }
        #endregion

        #region OneClickBoolColumn Implementation
       
        // If there is a click on a dicontinued row, want the checkbox
        //      to be the active currentcell.
        // afterCurrentCellChanged is set in dataGrid1_CurrentCellChanged.
        private void dataGrid1_Click(object sender, System.EventArgs e)
        {
            Point pt = this.dataGrid1.PointToClient(Control.MousePosition);
            DataGrid.HitTestInfo hti = this.dataGrid1.HitTest(pt);
            BindingManagerBase bmb = this.BindingContext[this.dataGrid1.DataSource, this.dataGrid1.DataMember];
            if(afterCurrentCellChanged && hti.Row < bmb.Count
                && hti.Type == DataGrid.HitTestType.Cell
                &&  hti.Column == checkCol )
            {   
                this.dataGrid1[hti.Row, checkCol] = !(bool)this.dataGrid1[hti.Row, checkCol];
                RefreshRow(hti.Row);
            }
            afterCurrentCellChanged = false;
        }
        #endregion

        #region Helper Methods

        // Forces a repaint of given row.
        private void RefreshRow(int row)
        {
            Rectangle rect = this.dataGrid1.GetCellBounds(row, 0);
            rect = new Rectangle(rect.Right, rect.Top, this.dataGrid1.Width, rect.Height);
            this.dataGrid1.Invalidate(rect);
        }

        // Given a row, computes whether product needs tobe reordered.
        private bool NeedToReorder(int row)
        {
            int unitsInStock = (Int16) this.dataGrid1[row,  this.unitsInStockCol];
            int unitsOnOrder = (Int16) this.dataGrid1[row,  this.unitsOnOrderCol];
            int reorderLevel = (Int16) this.dataGrid1[row,  this.reorderLevelCol];

            return (reorderLevel > (unitsInStock + unitsOnOrder));
        }

        //DataGrid.CurrentCellChanged used to:
        //    Force current cell to bool column if click on discontinued row.
        //    Set afterCurrentCellFlag which is part of the OneClickBoolColumn.
        private bool afterCurrentCellChanged = false;
        private void dataGrid1_CurrentCellChanged(object sender, System.EventArgs e)
        {
            //if click on a discontinued row, then set currrentcell to checkbox
            if((bool)this.dataGrid1[this.dataGrid1.CurrentRowIndex, checkCol])
                this.dataGrid1.CurrentCell = new DataGridCell(this.dataGrid1.CurrentRowIndex, checkCol);
            afterCurrentCellChanged = true;
        }
        #endregion
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值