爲了增加DataGridViewComboBoxColumn列類型的下拉事件,我重新定義了該類爲:DataGridViewComboBoxNewColumn,並增加事件,請高手看看,單擊下拉事件時,總是提示:未將對象引用對象的實例的錯誤.
代碼如下:
- using System;
- using System.Data;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.Collections.Generic;
- using System.Design;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Drawing.Drawing2D;
- using System.Diagnostics;
- using System.Windows.Forms;
- namespace BCB.WindowsUI.Control.Controls2
- {
- public class DataGridViewComboBoxNewColumn : DataGridViewColumn
- {
- /// <summary>
- /// 內部控件。
- /// </summary>
- private ComboxBoxEditingControl innerControl;
- public DataGridViewComboBoxNewColumn(): base(new DataGridViewComboBoxNewCell())
- {
- innerControl = new ComboxBoxEditingControl();
- innerControl.SetParentColumn(this);
- }
- /// <summary>
- /// 查看內部控件。
- /// </summary>
- public ComboxBoxEditingControl InnerComboBox
- {
- get { return innerControl;}
- }
- #region 重載事件
- public override DataGridViewCell CellTemplate
- {
- get
- {
- return base.CellTemplate;
- }
- set
- {
- if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewComboBoxNewCell)))
- {
- throw new InvalidCastException("應是DataGridViewComboBoxNewCell,非法類型!");
- }
- base.CellTemplate = value;
- }
- }
- /// <summary>
- /// 顯示區域。
- /// </summary>
- public override bool Displayed
- {
- get
- {
- return base.Displayed;
- }
- }
- /// <summary>
- /// 只讀屬性。
- /// </summary>
- public override bool ReadOnly
- {
- get
- {
- return base.ReadOnly;
- }
- set
- {
- base.ReadOnly = value;
- }
- }
- /// <summary>
- /// 三種狀態。
- /// </summary>
- public override DataGridViewTriState Resizable
- {
- get
- {
- return base.Resizable;
- }
- set
- {
- base.Resizable = value;
- }
- }
- protected override void OnDataGridViewChanged()
- {
- base.OnDataGridViewChanged();
- }
- public override DataGridViewCellStyle DefaultCellStyle
- {
- get
- {
- return base.DefaultCellStyle;
- }
- set
- {
- base.DefaultCellStyle = value;
- }
- }
- /// <summary>
- /// 克隆列。
- /// </summary>
- /// <returns></returns>
- public override object Clone()
- {
- DataGridViewComboBoxNewColumn comboBoxCol = (DataGridViewComboBoxNewColumn)base.Clone();
- comboBoxCol.DataSource = this._DataSource;
- comboBoxCol.DisplayMember = this._DisplayMember;
- comboBoxCol.ValueMember = this._ValueMember;
- comboBoxCol.innerControl = this.innerControl;
- comboBoxCol.Events = this._events;
- return comboBoxCol;
- }
- #endregion
- /// <summary>
- /// 數據源。
- /// </summary>
- public Object DataSource
- {
- get { return _DataSource; }
- set { _DataSource = value; }
- }private Object _DataSource = null;
- /// <summary>
- /// 顯示的數據字段名稱。
- /// </summary>
- public String DisplayMember
- {
- get { return _DisplayMember; }
- set { _DisplayMember = value; }
- }private String _DisplayMember = String.Empty;
- /// <summary>
- /// 實際數據值。
- /// </summary>
- public String ValueMember
- {
- get { return _ValueMember; }
- set { _ValueMember = value; }
- }private String _ValueMember = String.Empty;
- /// <summary>
- /// SelectedValueChanged 委託事件列表。
- /// </summary>
- public event EventHandler SelectedIndexChanged
- {
- add { Events.AddHandler(EventSelectedIndexChanged, value); }
- remove { Events.RemoveHandler(EventSelectedIndexChanged, value); }
- }static readonly Object EventSelectedIndexChanged = new Object();
- /// <summary>
- /// OnSelectedValueChaned 事件觸發器。
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnSelectedIndexChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
- if (handler != null) handler(this, e);
- }
- /// <summary>
- /// SelectedValueChanged 委託事件列表。
- /// </summary>
- public event EventHandler SelectedValueChanged
- {
- add { Events.AddHandler(EventSelectedValueChanged, value); }
- remove { Events.RemoveHandler(EventSelectedValueChanged, value); }
- }static readonly Object EventSelectedValueChanged = new Object();
- /// <summary>
- /// OnSelectedValueChaned 事件觸發器。
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnSelectedValueChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[EventSelectedValueChanged];
- if (handler != null) handler(this, e);
- }
- /// <summary>
- /// 事件委代列表。
- /// </summary>
- protected EventHandlerList Events
- {
- get
- {
- if (_events == null)
- _events = new EventHandlerList();
- return _events;
- }
- set
- {
- _events =(EventHandlerList)value;
- }
- }private EventHandlerList _events;
- #region 內部相關類
- /// <summary>
- /// 單元格控件呈現。
- /// </summary>
- internal class DataGridViewComboBoxNewCell : DataGridViewComboBoxCell
- {
- public DataGridViewComboBoxNewCell()
- : base()
- {
- }
- public override void InitializeEditingControl(int rowIndex, object
- initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
- {
- // Set the value of the editing control to the current cell value.
- base.InitializeEditingControl(rowIndex, initialFormattedValue,
- dataGridViewCellStyle);
- ComboxBoxEditingControl comboBoxControl =
- DataGridView.EditingControl as ComboxBoxEditingControl;
- //設置開始時抑制事件。
- comboBoxControl.SuppressEvent = true;
- DataGridViewComboBoxNewColumn parentColumn = (DataGridViewComboBoxNewColumn)this.OwningColumn;
- comboBoxControl.DataSource = parentColumn.DataSource;
- comboBoxControl.DisplayMember = parentColumn.DisplayMember;
- comboBoxControl.ValueMember = parentColumn.ValueMember;
- //結束設置後不抑制事件。
- comboBoxControl.SuppressEvent = false;
- if (!Convert.IsDBNull(Value))
- {
- comboBoxControl.Text = (String)Value;
- }
- }
- [Browsable(true)]
- public override Type EditType
- {
- get
- {
- // Return the type of the editing contol that CalendarCell uses.
- return typeof(ComboxBoxEditingControl);
- }
- }
- public override Type ValueType
- {
- get
- {
- // Return the type of the value that CalendarCell contains.
- return typeof(String);
- }
- }
- /// <summary>
- /// 重載單元格克隆。
- /// </summary>
- /// <returns></returns>
- public override object Clone()
- {
- DataGridViewComboBoxNewCell comboBoxCell = (DataGridViewComboBoxNewCell)base.Clone();
- return comboBoxCell;
- }
- /// <summary>
- /// 重繪控件。
- /// </summary>
- /// <param name="graphics"></param>
- /// <param name="clipBounds"></param>
- /// <param name="cellBounds"></param>
- /// <param name="rowIndex"></param>
- /// <param name="elementState"></param>
- /// <param name="value"></param>
- /// <param name="formattedValue"></param>
- /// <param name="errorText"></param>
- /// <param name="cellStyle"></param>
- /// <param name="advancedBorderStyle"></param>
- /// <param name="paintParts"></param>
- protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
- {
- base.Paint(graphics, clipBounds, cellBounds, rowIndex,
- elementState, value, formattedValue, errorText,
- cellStyle, advancedBorderStyle, paintParts);
- Point cursorPnt = DataGridView.PointToClient(Cursor.Position);
- if (cellBounds.Contains(cursorPnt))
- {
- Rectangle newRect = new Rectangle(cellBounds.X + 1, cellBounds.Y + 1,
- cellBounds.Width - 4, cellBounds.Height - 4);
- graphics.DrawRectangle(Pens.Brown, newRect);
- }
- }
- protected override void OnMouseEnter(int rowIndex)
- {
- base.OnMouseEnter(rowIndex);
- this.DataGridView.InvalidateCell(this);
- }
- protected override void OnMouseLeave(int rowIndex)
- {
- base.OnMouseLeave(rowIndex);
- this.DataGridView.InvalidateCell(this);
- }
- }
- /// <summary>
- /// 承載數據控件。
- /// </summary>
- public class ComboxBoxEditingControl : ComboBox, IDataGridViewEditingControl
- {
- DataGridView _dataGridView;
- DataGridViewComboBoxNewColumn _parentColumn;
- private bool valueChanged = false;
- int rowIndex;
- public ComboxBoxEditingControl()
- {
- DropDownStyle = ComboBoxStyle.DropDownList;
- }
- /// <summary>
- /// 設置父列。
- /// </summary>
- /// <param name="parentColumn"></param>
- public void SetParentColumn(DataGridViewComboBoxNewColumn parentColumn)
- {
- _dataGridView = parentColumn.DataGridView;
- _parentColumn = parentColumn;
- }
- /// <summary>
- /// 重載基類文本改變事件。
- /// </summary>
- /// <param name="e"></param>
- protected override void OnTextChanged(EventArgs e)
- {
- base.OnTextChanged(e);
- NotifyValueChangeOfDataGridView();
- }
- /// <summary>
- /// 重載事件。
- /// </summary>
- /// <param name="e"></param>
- protected override void OnSelectedValueChanged(EventArgs e)
- {
- base.OnSelectedValueChanged(e);
- NotifyValueChangeOfDataGridView();
- if (!SuppressEvent) _parentColumn.OnSelectedValueChanged(e);
- }
- protected override void OnSelectedIndexChanged(EventArgs e)
- {
- base.OnSelectedIndexChanged(e);
- NotifyValueChangeOfDataGridView();
- if (!SuppressEvent) _parentColumn.OnSelectedIndexChanged(e);
- }
- /// <summary>
- /// 提示數據發生改變。
- /// </summary>
- private void NotifyValueChangeOfDataGridView()
- {
- valueChanged = true;
- this._dataGridView.NotifyCurrentCellDirty(true);
- }
- /// <summary>
- /// 編輯文本時光標形狀。
- /// </summary>
- public Cursor EditingPanelCursor
- {
- get
- {
- return Cursors.IBeam;
- }
- }
- /// <summary>
- /// 獲取或設置所在的DataGridView.
- /// </summary>
- public DataGridView EditingControlDataGridView
- {
- get { return _dataGridView; }
- set { _dataGridView = (DataGridView)value; }
- }
- /// <summary>
- /// 獲取或設置格式化後的值.
- /// </summary>
- public object EditingControlFormattedValue
- {
- get
- {
- return this.Text;
- }
- set
- {
- Text = value as String;
- NotifyValueChangeOfDataGridView();
- }
- }
- /// <summary>
- /// 獲取控件的Text值.
- /// </summary>
- /// <param name="context"></param>
- /// <returns></returns>
- public object GetEditingControlFormattedValue(
- DataGridViewDataErrorContexts context)
- {
- return EditingControlFormattedValue;
- }
- /// <summary>
- /// 設置樣式.
- /// </summary>
- /// <param name="dataGridViewCellStyle"></param>
- public void ApplyCellStyleToEditingControl(
- DataGridViewCellStyle dataGridViewCellStyle)
- {
- this.Font = dataGridViewCellStyle.Font;
- this.ForeColor = dataGridViewCellStyle.ForeColor;
- this.BackColor = dataGridViewCellStyle.BackColor;
- }
- /// <summary>
- /// 控件所在行.
- /// </summary>
- public int EditingControlRowIndex
- {
- get
- {
- return rowIndex;
- }
- set
- {
- rowIndex = value;
- }
- }
- /// <summary>
- /// 編輯鍵盤.
- /// </summary>
- /// <param name="key"></param>
- /// <param name="dataGridViewWantsInputKey"></param>
- /// <returns></returns>
- public bool EditingControlWantsInputKey(
- Keys key, bool dataGridViewWantsInputKey)
- { // Let the ComboBox handle the keys listed.
- switch (key & Keys.KeyCode)
- {
- case Keys.Left:
- case Keys.Up:
- case Keys.Down:
- case Keys.Right:
- case Keys.Home:
- case Keys.End:
- case Keys.PageDown:
- case Keys.PageUp:
- return true;
- default:
- return false;
- }
- }
- // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit
- // method.
- public void PrepareEditingControlForEdit(bool selectAll)
- {
- // No preparation needs to be done.
- }
- // Implements the IDataGridViewEditingControl
- // .RepositionEditingControlOnValueChange property.
- public bool RepositionEditingControlOnValueChange
- {
- get
- {
- return false;
- }
- }
- /// <summary>
- /// 是否值發生了變化.
- /// </summary>
- public bool EditingControlValueChanged
- {
- get
- {
- return valueChanged;
- }
- set
- {
- valueChanged = value;
- }
- }
- /// <summary>
- /// 是否觸發事件。
- /// </summary>
- public bool SuppressEvent
- {
- get { return _suppressEvent; }
- set { _suppressEvent = value; }
- } bool _suppressEvent;
- }
- #endregion
- }
- }
運行的代代碼:
其中:報錯的地方:if (!SuppressEvent) _parentColumn.OnSelectedIndexChanged(e);
變量_parentColumn沒有引用實例,可明明設置父列對象的.
請高手指教,謝謝!