Sb9-关于使用别人封装的C#控件出现异常如何处理

发布时间 2023-12-12 14:36:01作者: 晨耕暮饮

偶然间我在网上看到一个封装了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
View Code

异常详细信息我贴在上面了。很奇怪的现象,不知道问题出在哪里,然后我就看了一下这个“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;
        }
    }
View Code

但是调试状态没法进入他的代码体中,反正我可以断定是这个键盘事件中肯定存在某个对象是空的,本来想按照他的代码重新写一遍,这样就可以调试了,但是这个“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;
            }
        }
}
View Code

此处我们重写的OnKeyDown事件代码和“ExpandableGridView.dll”类库中TreeGridView的OnKeyDown事件代码一模一样(实际就是想能够进入调试这个代码),但是我们必须先注释掉“base.OnKeyDown(e);”代码,不然直接进入了“ExpandableGridView.dll”类库中TreeGridView的OnKeyDown事件,就没法继续调试错误了。

问题找到了,原来是因为当按下回车的时候控件的CurrentCell是空值,所以直接抛出了异常。没办法了,毕竟代码用了很多次这个控件,直接重新封装一下,在捕获键盘事件后,首先判断一下CurrentCell是否为空,若是空的就不做任何处理了。