为了增加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没有引用实例,可明明设置父列对象的.
请高手指教,谢谢!