重寫DataGridViewColumn


做個項目需要用到DataGridView,這個控件還是挺好用的,但是今天卻發現無法實現自己想要的功能。主要是DataGridViewCheckBoxColumn這個列雖然是提供了復選框,但是卻未能在復選框的旁邊提供文本的顯示。在網上搜索了一下,提供的方法很多都是弄兩列,然后合並單元格,將兩列合並成為了一列。不過我不太喜歡那種方式,於是就自己重寫了一下DataGridViewColumn,略顯簡陋,只實現了最基本的功能,現在拿出來,希望各位能夠提一些好的意見和見解。

首先定義一個實現了 IDataGridViewEditingControl 接口的類

  class DataGridViewCheckBoxTextControl : CheckBox, IDataGridViewEditingControl
    {
        /// <summary>
        /// 當前所在表格
        /// </summary>
        private DataGridView MyDataGridView { set; get; }
        /// <summary>
        /// 值是否發生更改
        /// </summary>
        private bool ValueChanged { set; get; }
        /// <summary>
        /// 當前所在行
        /// </summary>
        private int RowIndex { set; get; }

        protected override void OnCheckedChanged(EventArgs e)
        {
            ValueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnCheckedChanged(e);
        }

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            Font = dataGridViewCellStyle.Font;
            ForeColor = dataGridViewCellStyle.ForeColor;
            BackColor = dataGridViewCellStyle.BackColor;
        }

        public DataGridView EditingControlDataGridView
        {
            get
            {
                return MyDataGridView;
            }
            set
            {
                MyDataGridView = value;
            }
        }

        public object EditingControlFormattedValue
        {
            get
            {
                return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
            }
            set
            {
                Checked = value == null ? false : (bool)value;
            }
        }

        public int EditingControlRowIndex
        {
            get
            {
                return RowIndex;
            }
            set
            {
                RowIndex = value;
            }
        }

        public bool EditingControlValueChanged
        {
            get
            {
                return ValueChanged;
            }
            set
            {
                ValueChanged = value;
            }
        }

        public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.LButton:
                    return !dataGridViewWantsInputKey;
            }
            return !dataGridViewWantsInputKey;
        }

        public Cursor EditingPanelCursor
        {
            get { return Cursors.Default; }
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return this.Checked;
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {

        }

        public bool RepositionEditingControlOnValueChange
        {
            get { return false; }
        }
    }

其次定義重寫這個列所需要的單元格

   public class DataGridViewCheckBoxTextCell : DataGridViewCell
    {
        public DataGridViewCheckBoxTextCell() : base() { }

        private static Type defaultEditType = typeof(DataGridViewCheckBoxTextControl);
        private static Type defaultValueType = typeof(System.Boolean);

        public override Type EditType
        {
            get { return defaultEditType; }
        }

        /// <summary>
        /// 單元格邊框顏色
        /// </summary>
        private Color CellBorderColor { get { return Color.FromArgb(172, 168, 153); } }

        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)
        {
            var check = (Boolean)value;
            if (paintParts == DataGridViewPaintParts.Background || paintParts == DataGridViewPaintParts.All)
            {
                graphics.FillRectangle(new SolidBrush(cellStyle.BackColor), cellBounds);
            }
            if (paintParts == DataGridViewPaintParts.Border || paintParts == DataGridViewPaintParts.All)
            {
                graphics.DrawRectangle(new Pen(CellBorderColor), cellBounds);
            }
            if (paintParts == DataGridViewPaintParts.SelectionBackground || Selected)
            {
                graphics.FillRectangle(new SolidBrush(cellStyle.SelectionBackColor), cellBounds);
            }
            var col = OwningColumn as DataGridViewCheckBoxTextColumn;
            if (col != null && !string.IsNullOrEmpty(col.Text))
            {
                graphics.DrawString(col.Text, cellStyle.Font, new SolidBrush(Selected ?
                    cellStyle.SelectionForeColor : cellStyle.ForeColor),
                    new Point(cellBounds.X + 25, cellBounds.Y + cellBounds.Height / 4));
            }
            CheckBoxRenderer.DrawCheckBox(graphics, new Point(cellBounds.X + 4, cellBounds.Y + cellBounds.Height / 4), CheckState);
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        }

        /// <summary>
        /// <summary>
        /// 當前復選框的狀態
        /// </summary>
        private CheckBoxState CheckState { set; get; }

        protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
        {
            var check = (bool)Value;
            CheckState = check ? CheckBoxState.CheckedPressed : CheckBoxState.UncheckedPressed;
            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
        {
            var check = (bool)Value;
            Value = !check;
            SetValue(RowIndex, Value);
            CheckState = check ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
            base.OnMouseUp(e);
        }

        public override Type ValueType
        {
            get
            {
                Type valueType = base.ValueType;
                if (valueType != null)
                {
                    return valueType;
                }
                return defaultValueType;
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return true;
            }
        }
    }

最后才需要再定義這個新建的列

    public class DataGridViewCheckBoxTextColumn : DataGridViewColumn
    {
        public DataGridViewCheckBoxTextColumn()
            : base()
        {
            CellTemplate = new DataGridViewCheckBoxTextCell();
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewCheckBoxTextCell)))
                {
                    throw new Exception("這個列里面必須綁定MyDataGridViewCheckBoxCell");
                }
                base.CellTemplate = value;
            }
        }

        public override object Clone()
        {
            DataGridViewCheckBoxTextColumn col = (DataGridViewCheckBoxTextColumn)base.Clone();
            col.Text = Text;
            return col;
        }

        public string Text { set; get; }


    }

如果這個列是定義在控件類庫內,那么引用到項目里面的時候,就能夠直接在編輯器內添加這個列。如圖:

最終效果圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM