自定义 DataGridViewColumn 类:DataGridViewComboBoxNewColumn

      

         为了增加DataGridViewComboBoxColumn列类型的下拉事件,我重新定义了该类为:DataGridViewComboBoxNewColumn,并增加事件,请高手看看,单击下拉事件时,总是提示:未将对象引用对象的实例的错误.

 

         代码如下:

  1. using System;
  2. using System.Data;
  3. using System.ComponentModel;
  4. using System.ComponentModel.Design;
  5. using System.Collections.Generic;
  6. using System.Design;
  7. using System.Drawing;
  8. using System.Drawing.Design;
  9. using System.Drawing.Drawing2D;
  10. using System.Diagnostics;
  11. using System.Windows.Forms;
  12. namespace BCB.WindowsUI.Control.Controls2
  13. {
  14.     public class DataGridViewComboBoxNewColumn : DataGridViewColumn
  15.     {
  16.         /// <summary>
  17.         /// 内部控件。 
  18.         /// </summary>
  19.         private ComboxBoxEditingControl innerControl;
  20.         public DataGridViewComboBoxNewColumn(): base(new DataGridViewComboBoxNewCell())
  21.         {
  22.             innerControl = new ComboxBoxEditingControl();
  23.             innerControl.SetParentColumn(this);
  24.         }
  25.         /// <summary>
  26.         /// 查看内部控件。
  27.         /// </summary>
  28.         public ComboxBoxEditingControl InnerComboBox
  29.         {
  30.             get { return innerControl;}
  31.         }
  32.         #region 重载事件
  33.         public override DataGridViewCell CellTemplate
  34.         {
  35.             get
  36.             {
  37.                 return base.CellTemplate;
  38.             }
  39.             set
  40.             {
  41.                 if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewComboBoxNewCell)))
  42.                 {
  43.                     throw new InvalidCastException("应是DataGridViewComboBoxNewCell,非法类型!");
  44.                 }
  45.                 base.CellTemplate = value;
  46.             }
  47.         }
  48.         /// <summary>
  49.         /// 显示区域。
  50.         /// </summary>
  51.         public override bool Displayed
  52.         {
  53.             get
  54.             {
  55.                 return base.Displayed;
  56.             }
  57.         }
  58.         /// <summary>
  59.         /// 只读属性。
  60.         /// </summary>
  61.         public override bool ReadOnly
  62.         {
  63.             get
  64.             {
  65.                 return base.ReadOnly;
  66.             }
  67.             set
  68.             {
  69.                 base.ReadOnly = value;
  70.             }
  71.         }
  72.         /// <summary>
  73.         /// 三种状态。
  74.         /// </summary>
  75.         public override DataGridViewTriState Resizable
  76.         {
  77.             get
  78.             {
  79.                 return base.Resizable;
  80.             }
  81.             set
  82.             {
  83.                 base.Resizable = value;
  84.             }
  85.         }
  86.         protected override void OnDataGridViewChanged()
  87.         {
  88.             base.OnDataGridViewChanged();
  89.         }
  90.         public override DataGridViewCellStyle DefaultCellStyle
  91.         {
  92.             get
  93.             {
  94.                 return base.DefaultCellStyle;
  95.             }
  96.             set
  97.             {
  98.                 base.DefaultCellStyle = value;
  99.             }
  100.         }
  101.         /// <summary>
  102.         /// 克隆列。
  103.         /// </summary>
  104.         /// <returns></returns>
  105.         public override object Clone()
  106.         {
  107.             DataGridViewComboBoxNewColumn comboBoxCol = (DataGridViewComboBoxNewColumn)base.Clone();
  108.             comboBoxCol.DataSource = this._DataSource;
  109.             comboBoxCol.DisplayMember = this._DisplayMember;
  110.             comboBoxCol.ValueMember = this._ValueMember;
  111.             comboBoxCol.innerControl = this.innerControl;
  112.             comboBoxCol.Events = this._events;
  113.             return comboBoxCol;
  114.         }
  115.         #endregion
  116.         /// <summary>
  117.         /// 数据源。
  118.         /// </summary>
  119.         public Object DataSource
  120.         {
  121.             get { return _DataSource; }
  122.             set { _DataSource = value; }
  123.         }private Object _DataSource = null;
  124.         /// <summary>
  125.         /// 显示的数据字段名称。
  126.         /// </summary>
  127.         public String DisplayMember
  128.         {
  129.             get { return _DisplayMember; }
  130.             set { _DisplayMember = value; }
  131.         }private String _DisplayMember = String.Empty;
  132.         /// <summary>
  133.         /// 实际数据值。
  134.         /// </summary>
  135.         public String ValueMember
  136.         {
  137.             get { return _ValueMember; }
  138.             set { _ValueMember = value; }
  139.         }private String _ValueMember = String.Empty;
  140.         /// <summary>
  141.         /// SelectedValueChanged 委托事件列表。
  142.         /// </summary>
  143.         public event EventHandler SelectedIndexChanged
  144.         {
  145.             add { Events.AddHandler(EventSelectedIndexChanged, value); }
  146.             remove { Events.RemoveHandler(EventSelectedIndexChanged, value); }
  147.         }static readonly Object EventSelectedIndexChanged = new Object();
  148.         /// <summary>
  149.         /// OnSelectedValueChaned 事件触发器。
  150.         /// </summary>
  151.         /// <param name="e"></param>
  152.         protected virtual void OnSelectedIndexChanged(EventArgs e)
  153.         {
  154.             EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
  155.             if (handler != null) handler(this, e);
  156.         }
  157.         /// <summary>
  158.         /// SelectedValueChanged 委托事件列表。
  159.         /// </summary>
  160.         public event EventHandler SelectedValueChanged
  161.         {
  162.             add { Events.AddHandler(EventSelectedValueChanged, value); }
  163.             remove { Events.RemoveHandler(EventSelectedValueChanged, value); }
  164.         }static readonly Object EventSelectedValueChanged = new Object();
  165.         /// <summary>
  166.         /// OnSelectedValueChaned 事件触发器。
  167.         /// </summary>
  168.         /// <param name="e"></param>
  169.         protected virtual void OnSelectedValueChanged(EventArgs e)
  170.         {
  171.             EventHandler handler = (EventHandler)Events[EventSelectedValueChanged];
  172.             if (handler != null) handler(this, e);
  173.         }
  174.         /// <summary>
  175.         /// 事件委代列表。
  176.         /// </summary>
  177.         protected EventHandlerList Events
  178.         {
  179.             get
  180.             {
  181.                 if (_events == null)
  182.                     _events = new EventHandlerList();
  183.                 return _events;
  184.             }
  185.             set
  186.             {
  187.                 _events =(EventHandlerList)value;
  188.             }
  189.         }private EventHandlerList _events;
  190.         #region 内部相关类
  191.         /// <summary>
  192.         /// 单元格控件呈现。
  193.         /// </summary>
  194.         internal class DataGridViewComboBoxNewCell : DataGridViewComboBoxCell
  195.         {
  196.             public DataGridViewComboBoxNewCell()
  197.                 : base()
  198.             {
  199.             }
  200.             public override void InitializeEditingControl(int rowIndex, object
  201.                 initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
  202.             {                
  203.                 // Set the value of the editing control to the current cell value.
  204.                 base.InitializeEditingControl(rowIndex, initialFormattedValue,
  205.                     dataGridViewCellStyle);
  206.                 ComboxBoxEditingControl comboBoxControl =
  207.                     DataGridView.EditingControl as ComboxBoxEditingControl;
  208.                 //设置开始时抑制事件。
  209.                 comboBoxControl.SuppressEvent = true;
  210.                 DataGridViewComboBoxNewColumn parentColumn = (DataGridViewComboBoxNewColumn)this.OwningColumn;
  211.                 comboBoxControl.DataSource = parentColumn.DataSource;
  212.                 comboBoxControl.DisplayMember = parentColumn.DisplayMember;
  213.                 comboBoxControl.ValueMember = parentColumn.ValueMember;
  214.                 //结束设置后不抑制事件。
  215.                 comboBoxControl.SuppressEvent = false;
  216.                 if (!Convert.IsDBNull(Value))
  217.                 {
  218.                     comboBoxControl.Text = (String)Value;
  219.                 }
  220.             }
  221.             [Browsable(true)]
  222.             public override Type EditType
  223.             {
  224.                 get
  225.                 {
  226.                     // Return the type of the editing contol that CalendarCell uses.
  227.                     return typeof(ComboxBoxEditingControl);
  228.                 }
  229.             }
  230.             public override Type ValueType
  231.             {
  232.                 get
  233.                 {
  234.                     // Return the type of the value that CalendarCell contains.
  235.                     return typeof(String);
  236.                 }
  237.             }
  238.             /// <summary>
  239.             /// 重载单元格克隆。
  240.             /// </summary>
  241.             /// <returns></returns>
  242.             public override object Clone()
  243.             {
  244.                 DataGridViewComboBoxNewCell comboBoxCell = (DataGridViewComboBoxNewCell)base.Clone();
  245.                 return comboBoxCell;
  246.             }
  247.             /// <summary>
  248.             /// 重绘控件。
  249.             /// </summary>
  250.             /// <param name="graphics"></param>
  251.             /// <param name="clipBounds"></param>
  252.             /// <param name="cellBounds"></param>
  253.             /// <param name="rowIndex"></param>
  254.             /// <param name="elementState"></param>
  255.             /// <param name="value"></param>
  256.             /// <param name="formattedValue"></param>
  257.             /// <param name="errorText"></param>
  258.             /// <param name="cellStyle"></param>
  259.             /// <param name="advancedBorderStyle"></param>
  260.             /// <param name="paintParts"></param>
  261.             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)
  262.             {
  263.                 base.Paint(graphics, clipBounds, cellBounds, rowIndex,
  264.                     elementState, value, formattedValue, errorText,
  265.                     cellStyle, advancedBorderStyle, paintParts);
  266.                 Point cursorPnt = DataGridView.PointToClient(Cursor.Position);
  267.                 if (cellBounds.Contains(cursorPnt))
  268.                 {
  269.                     Rectangle newRect = new Rectangle(cellBounds.X + 1, cellBounds.Y + 1,
  270.                                                       cellBounds.Width - 4, cellBounds.Height - 4);
  271.                     graphics.DrawRectangle(Pens.Brown, newRect);
  272.                 }
  273.                 
  274.             }
  275.             protected override void OnMouseEnter(int rowIndex)
  276.             {
  277.                 base.OnMouseEnter(rowIndex);
  278.                 this.DataGridView.InvalidateCell(this);
  279.             }
  280.             protected override void OnMouseLeave(int rowIndex)
  281.             {
  282.                 base.OnMouseLeave(rowIndex);
  283.                 this.DataGridView.InvalidateCell(this);
  284.             }
  285.         }
  286.         /// <summary>
  287.         /// 承载数据控件。
  288.         /// </summary>
  289.         public class ComboxBoxEditingControl : ComboBox, IDataGridViewEditingControl
  290.         {
  291.             DataGridView _dataGridView;
  292.             DataGridViewComboBoxNewColumn _parentColumn;
  293.             private bool valueChanged = false;
  294.             int rowIndex;
  295.             public ComboxBoxEditingControl()
  296.             {
  297.                 DropDownStyle = ComboBoxStyle.DropDownList;
  298.             }
  299.             /// <summary>
  300.             /// 设置父列。
  301.             /// </summary>
  302.             /// <param name="parentColumn"></param>
  303.             public void SetParentColumn(DataGridViewComboBoxNewColumn parentColumn)
  304.             {
  305.                 _dataGridView = parentColumn.DataGridView;
  306.                 _parentColumn = parentColumn;
  307.             }
  308.             /// <summary>
  309.             /// 重载基类文本改变事件。
  310.             /// </summary>
  311.             /// <param name="e"></param>
  312.             protected override void OnTextChanged(EventArgs e)
  313.             {
  314.                 base.OnTextChanged(e);
  315.                 NotifyValueChangeOfDataGridView();
  316.             }
  317.             /// <summary>
  318.             /// 重载事件。
  319.             /// </summary>
  320.             /// <param name="e"></param>
  321.             protected override void OnSelectedValueChanged(EventArgs e)
  322.             {
  323.                 base.OnSelectedValueChanged(e);
  324.                 NotifyValueChangeOfDataGridView();
  325.                 if (!SuppressEvent) _parentColumn.OnSelectedValueChanged(e);
  326.             }
  327.             protected override void OnSelectedIndexChanged(EventArgs e)
  328.             {
  329.                 base.OnSelectedIndexChanged(e);
  330.                 NotifyValueChangeOfDataGridView();
  331.                 if (!SuppressEvent) _parentColumn.OnSelectedIndexChanged(e);
  332.             }
  333.             /// <summary>
  334.             /// 提示数据发生改变。
  335.             /// </summary>
  336.             private void NotifyValueChangeOfDataGridView()
  337.             {
  338.                 valueChanged = true;
  339.                 this._dataGridView.NotifyCurrentCellDirty(true);
  340.             }
  341.             /// <summary>
  342.             /// 编辑文本时光标形状。
  343.             /// </summary>
  344.             public Cursor EditingPanelCursor
  345.             {
  346.                 get
  347.                 {
  348.                     return Cursors.IBeam;
  349.                 }
  350.             }
  351.             /// <summary>
  352.             /// 获取或设置所在的DataGridView.
  353.             /// </summary>
  354.             public DataGridView EditingControlDataGridView
  355.             {
  356.                 get { return _dataGridView; }
  357.                 set { _dataGridView = (DataGridView)value; }
  358.             }
  359.             /// <summary>
  360.             /// 获取或设置格式化后的值.
  361.             /// </summary>
  362.             public object EditingControlFormattedValue
  363.             {
  364.                 get
  365.                 {
  366.                     return this.Text;
  367.                 }
  368.                 set
  369.                 {
  370.                     Text = value as String;
  371.                     NotifyValueChangeOfDataGridView();
  372.                 }
  373.             }
  374.             /// <summary>
  375.             /// 获取控件的Text值.
  376.             /// </summary>
  377.             /// <param name="context"></param>
  378.             /// <returns></returns>
  379.             public object GetEditingControlFormattedValue(
  380.                 DataGridViewDataErrorContexts context)
  381.             {
  382.                 return EditingControlFormattedValue;
  383.             }
  384.             /// <summary>
  385.             /// 设置样式.
  386.             /// </summary>
  387.             /// <param name="dataGridViewCellStyle"></param>
  388.             public void ApplyCellStyleToEditingControl(
  389.                 DataGridViewCellStyle dataGridViewCellStyle)
  390.             {
  391.                 this.Font = dataGridViewCellStyle.Font;
  392.                 this.ForeColor = dataGridViewCellStyle.ForeColor;
  393.                 this.BackColor = dataGridViewCellStyle.BackColor;
  394.             }
  395.             /// <summary>
  396.             /// 控件所在行.
  397.             /// </summary>
  398.             public int EditingControlRowIndex
  399.             {
  400.                 get
  401.                 {
  402.                     return rowIndex;
  403.                 }
  404.                 set
  405.                 {
  406.                     rowIndex = value;
  407.                 }
  408.             }
  409.             /// <summary>
  410.             /// 编辑键盘.
  411.             /// </summary>
  412.             /// <param name="key"></param>
  413.             /// <param name="dataGridViewWantsInputKey"></param>
  414.             /// <returns></returns>
  415.             public bool EditingControlWantsInputKey(
  416.                 Keys key, bool dataGridViewWantsInputKey)
  417.             {  // Let the ComboBox handle the keys listed.
  418.                 switch (key & Keys.KeyCode)
  419.                 {
  420.                     case Keys.Left:
  421.                     case Keys.Up:
  422.                     case Keys.Down:
  423.                     case Keys.Right:
  424.                     case Keys.Home:
  425.                     case Keys.End:
  426.                     case Keys.PageDown:
  427.                     case Keys.PageUp:
  428.                         return true;
  429.                     default:
  430.                         return false;
  431.                 }
  432.             }
  433.             // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
  434.             // method.
  435.             public void PrepareEditingControlForEdit(bool selectAll)
  436.             {
  437.                 // No preparation needs to be done.
  438.             }
  439.             // Implements the IDataGridViewEditingControl
  440.             // .RepositionEditingControlOnValueChange property.
  441.             public bool RepositionEditingControlOnValueChange
  442.             {
  443.                 get
  444.                 {
  445.                     return false;
  446.                 }
  447.             }
  448.             /// <summary>
  449.             /// 是否值发生了变化.
  450.             /// </summary>
  451.             public bool EditingControlValueChanged
  452.             {
  453.                 get
  454.                 {
  455.                     return valueChanged;
  456.                 }
  457.                 set
  458.                 {
  459.                     valueChanged = value;
  460.                 }
  461.             }
  462.             /// <summary>
  463.             /// 是否触发事件。
  464.             /// </summary>
  465.             public bool SuppressEvent
  466.             {
  467.                 get { return _suppressEvent; }
  468.                 set { _suppressEvent = value; }
  469.             } bool _suppressEvent;
  470.         }
  471.         #endregion
  472.     }
  473. }

运行的代代码:

 

其中:报错的地方:if (!SuppressEvent) _parentColumn.OnSelectedIndexChanged(e);

变量_parentColumn没有引用实例,可明明设置父列对象的.

 

请高手指教,谢谢!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值