Sb9-关于使用别人封装的C#控件出现异常如何处理
偶然间我在网上看到一个封装了DataGridView控件的第三方控件,里面有很多是我需要的效果。所以就直接拿来使用了,但是今天突然发现,这个控件里面的“TreeGridView”表格控件在没有绑定数据的时候,如果点击回车键的话会抛出一个空指针的异常。
在 AdvancedDataGridView.TreeGridView.OnKeyDown(KeyEventArgs e) 在 System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m) 在 System.Windows.Forms.DataGridView.ProcessKeyEventArgs(Message& m) 在 System.Windows.Forms.Control.ProcessKeyMessage(Message& m) 在 System.Windows.Forms.Control.WmKeyChar(Message& m) 在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.DataGridView.WndProc(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 在 System.Windows.Forms.Application.Run(Form mainForm) 在 ProductionToolPlatSystem.Program.RunMain() 在 D:\ZYJ\myCode\word\任务4-测试软件重新整合\ProductionPlatformV4.5-升级版本\ProductionPlatSystem\ProductionToolPlatSystem\Program.cs 中: 第 44 行
异常详细信息我贴在上面了。很奇怪的现象,不知道问题出在哪里,然后我就看了一下这个“ExpandableGridView.dll”的源码,我就发现这个动态库中我使用的TreeGridView中存在捕获键盘事件:
protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.Handled) { return; } if (e.KeyCode == Keys.F2 && base.CurrentCellAddress.X > -1 && base.CurrentCellAddress.Y > -1) { if (!base.CurrentCell.Displayed) { base.FirstDisplayedScrollingRowIndex = base.CurrentCellAddress.Y; } base.SelectionMode = DataGridViewSelectionMode.CellSelect; BeginEdit(selectAll: true); } else if (e.KeyCode == Keys.Return && !base.IsCurrentCellInEditMode) { base.SelectionMode = DataGridViewSelectionMode.FullRowSelect; base.CurrentCell.OwningRow.Selected = true; } }
但是调试状态没法进入他的代码体中,反正我可以断定是这个键盘事件中肯定存在某个对象是空的,本来想按照他的代码重新写一遍,这样就可以调试了,但是这个“ExpandableGridView.dll”类库中的代码太多了,懒得抄了,只能再封装一次吧。
我新建了一个UseControl控件,继承了所需要使用的TreeGridView控件,然后重写了他的OnKeyDown事件:
public partial class ExpandableGridViewControl : AdvancedDataGridView.TreeGridView { public ExpandableGridViewControl() { InitializeComponent(); } /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.Handled) { return; } if (e.KeyCode == Keys.F2 && base.CurrentCellAddress.X > -1 && base.CurrentCellAddress.Y > -1) { if (!base.CurrentCell.Displayed) { base.FirstDisplayedScrollingRowIndex = base.CurrentCellAddress.Y; } base.SelectionMode = DataGridViewSelectionMode.CellSelect; BeginEdit(selectAll: true); } else if (e.KeyCode == Keys.Return && !base.IsCurrentCellInEditMode) { base.SelectionMode = DataGridViewSelectionMode.FullRowSelect; base.CurrentCell.OwningRow.Selected = true; } } }
此处我们重写的OnKeyDown事件代码和“ExpandableGridView.dll”类库中TreeGridView的OnKeyDown事件代码一模一样(实际就是想能够进入调试这个代码),但是我们必须先注释掉“base.OnKeyDown(e);”代码,不然直接进入了“ExpandableGridView.dll”类库中TreeGridView的OnKeyDown事件,就没法继续调试错误了。
问题找到了,原来是因为当按下回车的时候控件的CurrentCell是空值,所以直接抛出了异常。没办法了,毕竟代码用了很多次这个控件,直接重新封装一下,在捕获键盘事件后,首先判断一下CurrentCell是否为空,若是空的就不做任何处理了。