private void _dataGridView_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            //这里的 DataGridViewElementStates.Selected 表示发生变更的状态是 Selected ,是否选中的状态发生了变化
            //而不是表示 由没选中变为被选中
            if (e.StateChanged == DataGridViewElementStates.Selected)
            {
                if (e.Row.Selected && ItemSelected != null)
                {
                    //因为有可能会选中多行,所以不能用 GetSelectedItem
                    //多选时GetSelectedItem只能拿一选中行中的第一行的绑定对象
                    GridViewControllerEventArgs args = new GridViewControllerEventArgs(
                        this.GetItem <object>(e.Row.Index), _currentCodon.DataBoundType);
                    ItemSelected(this, args);
                }

                if (e.Row.Selected == false && ItemUnSelected != null)
                {
                    GridViewControllerEventArgs args = new GridViewControllerEventArgs(
                        this.GetItem <object>(e.Row.Index), _currentCodon.DataBoundType);
                    ItemUnSelected(this, args);
                }
            }

            //如果是删除选中的行,不会触发 e.StateChanged == DataGridViewElementStates.Selected
            //而是会走到
            //e.StateChanged == DataGridViewElementStates.Displayed && e.Row.Index == -1
            //所以无法在删除选中行时触发 ItemUnSelected 事件
            //如果通过判断 e..StateChanged == DataGridViewElementStates.Displayed && e.Row.Index == -1
            //来实现,也不合理,因为删除行并不一定是手动删除的,可能是代码删除的,被删除的行之前就不是选中状态
        }
        private void _dataGridView_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0)
            {
                return;
            }

            if (DoubleClick != null)
            {
                GridViewControllerEventArgs args = new GridViewControllerEventArgs(
                    this.GetSelectedItem <object>(), _currentCodon.DataBoundType);
                DoubleClick(this, args);
            }

            //下钻
            if (GoingDown)
            {
                IList goingDownList = GetGoingDownItems();
                if (goingDownList != null)
                {
                    DataBind(goingDownList, _currentCodon.ItemType, GetSelectedItem());
                }
            }
        }