Beispiel #1
0
        /// <summary>
        ///     Handles special key bindings for key down events.  Base class handles space and tab.
        /// </summary>
        /// <param name="row">Index into this branch</param>
        /// <param name="column">Column index</param>
        /// <param name="key">Character typed by the user</param>
        /// <param name="modifiers">Any modifiers keys currently held down</param>
        /// <returns>ProcessKeyResult structure that indicates what action should be taken (if any)</returns>
        protected virtual ProcessKeyResult ProcessKeyDown(int row, int column, KeyEventArgs e)
        {
            var result = new ProcessKeyResult();

            result.Action    = KeyAction.Process;
            result.Direction = (e.Modifiers != Keys.Shift) ? NavigationDirection.Right : NavigationDirection.Left;
            switch (e.KeyCode)
            {
            case Keys.F2:
                result.Action         = KeyAction.Handle;
                result.StartLabelEdit = true;
                result.Direction      = NavigationDirection.Down;
                break;

            case Keys.Tab:
                result.Action     = KeyAction.Handle;
                result.ColumnType = null;
                break;

            case Keys.Space:
                if (_columns[column].ColumnIsCheckBox || InLabelEdit)
                {
                    // check box and text box columns should use default
                    // key processing for the space bar (toggle value)
                    result.Action = KeyAction.Process;
                }
                break;

            case Keys.Up:
                // let Ctrl-Up fall through to the base control processing.
                if (!e.Control)
                {
                    result.Action    = KeyAction.Handle;
                    result.Local     = false;
                    result.Direction = NavigationDirection.Up;
                }
                break;

            case Keys.Down:
                // let Ctrl-Down fall through to the base control processing.
                if (!e.Control)
                {
                    result.Action    = KeyAction.Handle;
                    result.Local     = false;
                    result.Direction = NavigationDirection.Down;
                    // Alt + Down should open a drop down
                    if (e.Alt)
                    {
                        result.StartLabelEdit = true;
                    }
                }
                break;

            case Keys.Delete:
                result.Action = KeyAction.Handle;
                result.Delete = true;
                break;
            }
            return(result);
        }
Beispiel #2
0
        /// <summary>
        ///     retrieves the column index given a type.  Assumes there
        ///     will only be a single instance of each type in the columns array.
        ///     returns -1 if the column is not found
        /// </summary>
        private int FindCurrentColumnOfType(ProcessKeyResult result)
        {
            var index = -1;

            int i;

            for (i = 0; i < _currentColumns.Length; i++)
            {
                var columnType = _currentColumns[i].GetType();
                if (result.ColumnType == null ||
                    columnType == result.ColumnType ||
                    columnType.IsSubclassOf(result.ColumnType))
                {
                    index = i;
                    break;
                }
            }

            return(index);
        }
        /// <summary>
        ///     Handles special key bindings for key down events.  Base class handles space and tab.
        /// </summary>
        /// <param name="row">Index into this branch</param>
        /// <param name="column">Column index</param>
        /// <param name="key">Character typed by the user</param>
        /// <param name="modifiers">Any modifiers keys currently held down</param>
        /// <returns>ProcessKeyResult structure that indicates what action should be taken (if any)</returns>
        protected virtual ProcessKeyResult ProcessKeyDown(int row, int column, KeyEventArgs e)
        {
            var result = new ProcessKeyResult();
            result.Action = KeyAction.Process;
            result.Direction = (e.Modifiers != Keys.Shift) ? NavigationDirection.Right : NavigationDirection.Left;
            switch (e.KeyCode)
            {
                case Keys.F2:
                    result.Action = KeyAction.Handle;
                    result.StartLabelEdit = true;
                    result.Direction = NavigationDirection.Down;
                    break;

                case Keys.Tab:
                    result.Action = KeyAction.Handle;
                    result.ColumnType = null;
                    break;

                case Keys.Space:
                    if (_columns[column].ColumnIsCheckBox || InLabelEdit)
                    {
                        // check box and text box columns should use default 
                        // key processing for the space bar (toggle value)
                        result.Action = KeyAction.Process;
                    }
                    break;

                case Keys.Up:
                    // let Ctrl-Up fall through to the base control processing.
                    if (!e.Control)
                    {
                        result.Action = KeyAction.Handle;
                        result.Local = false;
                        result.Direction = NavigationDirection.Up;
                    }
                    break;

                case Keys.Down:
                    // let Ctrl-Down fall through to the base control processing.
                    if (!e.Control)
                    {
                        result.Action = KeyAction.Handle;
                        result.Local = false;
                        result.Direction = NavigationDirection.Down;
                        // Alt + Down should open a drop down
                        if (e.Alt)
                        {
                            result.StartLabelEdit = true;
                        }
                    }
                    break;
                case Keys.Delete:
                    result.Action = KeyAction.Handle;
                    result.Delete = true;
                    break;
            }
            return result;
        }
        /// <summary>
        ///     Process key down events.
        /// </summary>
        public ProcessKeyResult ProcessKeyDown(int row, int column, KeyEventArgs e)
        {
            var result = new ProcessKeyResult(KeyAction.Process);
            if (e != null)
            {
                switch (e.KeyCode)
                {
                    case Keys.Tab:
                        result.Action = KeyAction.Handle;
                        result.Direction = !e.Shift ? NavigationDirection.Right : NavigationDirection.Left;
                        result.Local = false;
                        return result;
                    case Keys.Space:
                        if (_columns[column].ColumnIsCheckBox)
                        {
                            // if we're on a check box, use standard processing
                            return new ProcessKeyResult(KeyAction.Process);
                        }

                        // special case for only one checkbox in the row,
                        // it should be toggled no matter where the focus is.
                        var checkBoxIndex = -1;
                        for (var i = 0; i < _columns.Length; i++)
                        {
                            if (_columns[i].ColumnIsCheckBox
                                && (GetCheckBoxValue(row, i) != CheckBoxState.Unsupported))
                            {
                                if (checkBoxIndex == -1)
                                {
                                    checkBoxIndex = i;
                                }
                                else
                                {
                                    // more than one checkbox, use standard processing
                                    return new ProcessKeyResult(KeyAction.Process);
                                }
                            }

                            if (checkBoxIndex != -1)
                            {
                                ((IBranch)this).ToggleState(row, checkBoxIndex);

                                // need to refresh both ourselves and our children.  Do we need BranchModificationAction.ToggleState?
                                if (_onBranchModification != null)
                                {
                                    _onBranchModification(
                                        this,
                                        BranchModificationEventArgs.DisplayDataChanged(
                                            new DisplayDataChangedData(
                                                VirtualTreeDisplayDataChanges.StateImage, this, row, checkBoxIndex, 1)));
                                    _onBranchModification(
                                        this,
                                        BranchModificationEventArgs.DisplayDataChanged(
                                            new DisplayDataChangedData(
                                                VirtualTreeDisplayDataChanges.StateImage, _childBranchArray[row].Branch, -1, checkBoxIndex,
                                                -1)));
                                }

                                return new ProcessKeyResult(KeyAction.Discard); // we've handled this, no further processing necessary
                            }
                        }
                        break;

                    case Keys.Up:
                        // let Ctrl-Up fall through to the base control processing.
                        if (!e.Control)
                        {
                            result.Action = KeyAction.Handle;
                            result.Local = false;
                            result.Direction = NavigationDirection.Up;
                        }
                        break;

                    case Keys.Down:
                        // let Ctrl-Down fall through to the base control processing.
                        if (!e.Control)
                        {
                            result.Action = KeyAction.Handle;
                            result.Local = false;
                            result.Direction = NavigationDirection.Down;
                        }
                        break;
                }
            }

            return result;
        }
Beispiel #5
0
        /// <summary>
        ///     Process key down events.
        /// </summary>
        public ProcessKeyResult ProcessKeyDown(int row, int column, KeyEventArgs e)
        {
            var result = new ProcessKeyResult(KeyAction.Process);

            if (e != null)
            {
                switch (e.KeyCode)
                {
                case Keys.Tab:
                    result.Action    = KeyAction.Handle;
                    result.Direction = !e.Shift ? NavigationDirection.Right : NavigationDirection.Left;
                    result.Local     = false;
                    return(result);

                case Keys.Space:
                    if (_columns[column].ColumnIsCheckBox)
                    {
                        // if we're on a check box, use standard processing
                        return(new ProcessKeyResult(KeyAction.Process));
                    }

                    // special case for only one checkbox in the row,
                    // it should be toggled no matter where the focus is.
                    var checkBoxIndex = -1;
                    for (var i = 0; i < _columns.Length; i++)
                    {
                        if (_columns[i].ColumnIsCheckBox &&
                            (GetCheckBoxValue(row, i) != CheckBoxState.Unsupported))
                        {
                            if (checkBoxIndex == -1)
                            {
                                checkBoxIndex = i;
                            }
                            else
                            {
                                // more than one checkbox, use standard processing
                                return(new ProcessKeyResult(KeyAction.Process));
                            }
                        }

                        if (checkBoxIndex != -1)
                        {
                            ((IBranch)this).ToggleState(row, checkBoxIndex);

                            // need to refresh both ourselves and our children.  Do we need BranchModificationAction.ToggleState?
                            if (_onBranchModification != null)
                            {
                                _onBranchModification(
                                    this,
                                    BranchModificationEventArgs.DisplayDataChanged(
                                        new DisplayDataChangedData(
                                            VirtualTreeDisplayDataChanges.StateImage, this, row, checkBoxIndex, 1)));
                                _onBranchModification(
                                    this,
                                    BranchModificationEventArgs.DisplayDataChanged(
                                        new DisplayDataChangedData(
                                            VirtualTreeDisplayDataChanges.StateImage, _childBranchArray[row].Branch, -1, checkBoxIndex,
                                            -1)));
                            }

                            return(new ProcessKeyResult(KeyAction.Discard));    // we've handled this, no further processing necessary
                        }
                    }
                    break;

                case Keys.Up:
                    // let Ctrl-Up fall through to the base control processing.
                    if (!e.Control)
                    {
                        result.Action    = KeyAction.Handle;
                        result.Local     = false;
                        result.Direction = NavigationDirection.Up;
                    }
                    break;

                case Keys.Down:
                    // let Ctrl-Down fall through to the base control processing.
                    if (!e.Control)
                    {
                        result.Action    = KeyAction.Handle;
                        result.Local     = false;
                        result.Direction = NavigationDirection.Down;
                    }
                    break;
                }
            }

            return(result);
        }
        private bool ProcessKey(ProcessKeyResult result, ITreeGridDesignerBranch branch, int absIndex, int relIndex, int column)
        {
            var actionOccurred = false;
            var foundEditableColumn = false;
            var inLabelEdit = InLabelEdit;

            if (result.Action == KeyAction.Discard)
            {
                return true;
            }

            if (result.Action == KeyAction.Handle)
            {
                var treeDirection = TranslateNavigationDirection(result.Direction);
                if (result.StartLabelEdit)
                {
                    // key should just put us in edit mode
                    InLabelEdit = true;
                    // Alt + Down case - open drop down
                    if (result.Direction == NavigationDirection.Down)
                    {
                        var dropDown = LabelEditControl as TypeEditorHost;
                        if (dropDown != null)
                        {
                            dropDown.OpenDropDown();
                        }
                    }
                    return true; // currently, we don't allow combining this with other options
                }

                if (result.Delete)
                {
                    branch.Delete(relIndex, column);
                    // don't restore edit mode if we deleted something
                    inLabelEdit = false;
                }

                BatchDrawItem = true;
                if (inLabelEdit)
                {
                    var tridDesignerBranch = branch as TreeGridDesignerBranch;

                    if (tridDesignerBranch != null
                        && relIndex >= tridDesignerBranch.ElementCount)
                    {
                        // creator node edit.  unless the user has actually typed some text here,
                        // we treat this as non-edit mode (i.e, don't restore edit mode after navigation)
                        inLabelEdit = LabelEditControl.Text.Length > 0;
                    }
                }

                try
                {
                    InLabelEdit = false;

                    // the branch may block deactivation of the edit control,
                    // because of an incorrect entry, for example.  In that case,
                    // we should just get out.
                    if (InLabelEdit)
                    {
                        return false;
                    }

                    // expand branch first, if necesary
                    if (result.ExpandBranch)
                    {
                        // using column = 0 because TreeGrid designer
                        // doesn't support sub-item expansions.
                        if (!Tree.IsExpanded(absIndex, 0))
                        {
                            // the branch is requesting an expansion, but we can't do it.
                            // just get out and leave things the way they are.
                            if (!Tree.IsExpandable(absIndex, 0))
                            {
                                return false;
                            }

                            Tree.ToggleExpansion(absIndex, 0);
                            actionOccurred = true;
                        }
                    }

                    var branchType = branch.GetType();

                    if (result.ColumnType != null)
                    {
                        // limit search to a particular column
                        var newColumn = FindCurrentColumnOfType(result);

                        Debug.Assert(newColumn != -1, "Couldn't find column of type: " + result.ColumnType);
                        if ((treeDirection == TreeNavigation.RightColumn && column < newColumn)
                            || (treeDirection == TreeNavigation.LeftColumn && column > newColumn))
                        {
                            // in this case, we're done as long as the branch is of the appropriate type and supports navigation or is expandable, because we have
                            // the correct row/column indices.
                            column = newColumn;
                            foundEditableColumn = (result.BranchType == null || branchType == result.BranchType
                                                   || branchType.IsSubclassOf(result.BranchType)) &&
                                                  ((branch.GetValueSupported(relIndex, column)
                                                    & TreeGridDesignerValueSupportedStates.SupportsKeyboardNavigation) != 0
                                                   || (branch as IBranch).IsExpandable(relIndex, column));
                        }

                        if (!foundEditableColumn)
                        {
                            // need to do additional search, translate to an up or down search in this particular column
                            column = newColumn;
                            treeDirection = treeDirection == TreeNavigation.RightColumn ? TreeNavigation.Down : TreeNavigation.Up;
                        }
                    }

                    if (result.Delete)
                    {
                        // we are already focused on an editable column
                        InvalidateItem(CurrentIndex);
                        actionOccurred = true;
                    }
                    else
                    {
                        // search for next matching row/column
                        int oldAbsIndex;
                        while (!foundEditableColumn)
                        {
                            oldAbsIndex = absIndex;
                            if (treeDirection == TreeNavigation.LeftColumn
                                && column == 0)
                            {
                                absIndex--;
                                if (absIndex >= 0)
                                {
                                    var info = Tree.GetItemInfo(absIndex, 0, false);
                                    column = GetLastColumnIndex(info.Branch, info.Row);
                                }
                            }
                            else if (treeDirection == TreeNavigation.RightColumn
                                     && column == GetLastColumnIndex((IBranch)branch, relIndex))
                            {
                                absIndex++;
                                column = 0;
                            }
                            else if (result.ColumnType == null)
                            {
                                // search is not restricted to a particular column, so we translate up/down to 
                                // left/right search to give a better experience.
                                if (treeDirection == TreeNavigation.Up)
                                {
                                    absIndex--;
                                    treeDirection = TreeNavigation.LeftColumn;

                                    if (absIndex >= 0)
                                    {
                                        // handle jagged column cases
                                        var info = Tree.GetItemInfo(absIndex, 0, false);
                                        if (info.Branch != null)
                                        {
                                            column = GetLastColumnIndex(info.Branch, info.Row);
                                        }
                                    }
                                }
                                else if (treeDirection == TreeNavigation.Down)
                                {
                                    absIndex++;
                                    treeDirection = TreeNavigation.RightColumn;
                                    column = 0;
                                }
                            }

                            if (absIndex < 0
                                || absIndex >= Tree.VisibleItemCount)
                            {
                                break;
                            }

                            var coordinate = new VirtualTreeCoordinate(absIndex, column);
                            if (absIndex == oldAbsIndex)
                            {
                                // if the above didn't result in any navigation, ask the tree to do it itself.
                                coordinate = Tree.GetNavigationTarget(treeDirection, absIndex, column, ColumnPermutation);
                            }

                            if (coordinate.IsValid)
                            {
                                absIndex = coordinate.Row;
                                column = coordinate.Column;

                                if (oldAbsIndex != absIndex)
                                {
                                    // we've transitioned to a new row, retrieve new row data from the tree.
                                    var info = Tree.GetItemInfo(absIndex, 0, false);

                                    if (result.Local
                                        && branch != null
                                        && branch != info.Branch)
                                    {
                                        // stop search if we shouldn't go past current branch
                                        break;
                                    }

                                    branch = info.Branch as ITreeGridDesignerBranch;
                                    branchType = branch.GetType();
                                    relIndex = info.Row;
                                }

                                // allow focus on expandable cells or cells that support navigation that are of the appropriate branch type.  
                                if (branch != null
                                    &&
                                    (result.BranchType == null || branchType == result.BranchType
                                     || branchType.IsSubclassOf(result.BranchType))
                                    &&
                                    ((branch.GetValueSupported(relIndex, column)
                                      & TreeGridDesignerValueSupportedStates.SupportsKeyboardNavigation) != 0
                                     || (branch as IBranch).IsExpandable(relIndex, column)))
                                {
                                    foundEditableColumn = true;
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    if (foundEditableColumn)
                    {
                        var currentIndex = CurrentIndex;

                        if (absIndex != currentIndex)
                        {
                            if (currentIndex != -1)
                            {
                                // currentIndex may be -1 if we toggled expansion,
                                // but in that case the base control will take care
                                // of the redraw
                                // TODO : is this a bug in the control?  shouldn't selection
                                // be restored after toggling expansion?
                                InvalidateItem(currentIndex);
                            }

                            CurrentIndex = absIndex;
                            actionOccurred = true;
                        }

                        if (column != CurrentColumn)
                        {
                            CurrentColumn = column;
                            actionOccurred = true;
                        }
                    }

                    InLabelEdit = inLabelEdit;
                }
                finally
                {
                    BatchDrawItem = false;
                }
            }
            return actionOccurred;
        }
        /// <summary>
        ///     retrieves the column index given a type.  Assumes there
        ///     will only be a single instance of each type in the columns array.
        ///     returns -1 if the column is not found
        /// </summary>
        private int FindCurrentColumnOfType(ProcessKeyResult result)
        {
            var index = -1;

            int i;
            for (i = 0; i < _currentColumns.Length; i++)
            {
                var columnType = _currentColumns[i].GetType();
                if (result.ColumnType == null
                    || columnType == result.ColumnType
                    || columnType.IsSubclassOf(result.ColumnType))
                {
                    index = i;
                    break;
                }
            }

            return index;
        }
Beispiel #8
0
        private bool ProcessKey(ProcessKeyResult result, ITreeGridDesignerBranch branch, int absIndex, int relIndex, int column)
        {
            var actionOccurred      = false;
            var foundEditableColumn = false;
            var inLabelEdit         = InLabelEdit;

            if (result.Action == KeyAction.Discard)
            {
                return(true);
            }

            if (result.Action == KeyAction.Handle)
            {
                var treeDirection = TranslateNavigationDirection(result.Direction);
                if (result.StartLabelEdit)
                {
                    // key should just put us in edit mode
                    InLabelEdit = true;
                    // Alt + Down case - open drop down
                    if (result.Direction == NavigationDirection.Down)
                    {
                        var dropDown = LabelEditControl as TypeEditorHost;
                        if (dropDown != null)
                        {
                            dropDown.OpenDropDown();
                        }
                    }
                    return(true); // currently, we don't allow combining this with other options
                }

                if (result.Delete)
                {
                    branch.Delete(relIndex, column);
                    // don't restore edit mode if we deleted something
                    inLabelEdit = false;
                }

                BatchDrawItem = true;
                if (inLabelEdit)
                {
                    var tridDesignerBranch = branch as TreeGridDesignerBranch;

                    if (tridDesignerBranch != null &&
                        relIndex >= tridDesignerBranch.ElementCount)
                    {
                        // creator node edit.  unless the user has actually typed some text here,
                        // we treat this as non-edit mode (i.e, don't restore edit mode after navigation)
                        inLabelEdit = LabelEditControl.Text.Length > 0;
                    }
                }

                try
                {
                    InLabelEdit = false;

                    // the branch may block deactivation of the edit control,
                    // because of an incorrect entry, for example.  In that case,
                    // we should just get out.
                    if (InLabelEdit)
                    {
                        return(false);
                    }

                    // expand branch first, if necesary
                    if (result.ExpandBranch)
                    {
                        // using column = 0 because TreeGrid designer
                        // doesn't support sub-item expansions.
                        if (!Tree.IsExpanded(absIndex, 0))
                        {
                            // the branch is requesting an expansion, but we can't do it.
                            // just get out and leave things the way they are.
                            if (!Tree.IsExpandable(absIndex, 0))
                            {
                                return(false);
                            }

                            Tree.ToggleExpansion(absIndex, 0);
                            actionOccurred = true;
                        }
                    }

                    var branchType = branch.GetType();

                    if (result.ColumnType != null)
                    {
                        // limit search to a particular column
                        var newColumn = FindCurrentColumnOfType(result);

                        Debug.Assert(newColumn != -1, "Couldn't find column of type: " + result.ColumnType);
                        if ((treeDirection == TreeNavigation.RightColumn && column < newColumn) ||
                            (treeDirection == TreeNavigation.LeftColumn && column > newColumn))
                        {
                            // in this case, we're done as long as the branch is of the appropriate type and supports navigation or is expandable, because we have
                            // the correct row/column indices.
                            column = newColumn;
                            foundEditableColumn = (result.BranchType == null || branchType == result.BranchType ||
                                                   branchType.IsSubclassOf(result.BranchType)) &&
                                                  ((branch.GetValueSupported(relIndex, column)
                                                    & TreeGridDesignerValueSupportedStates.SupportsKeyboardNavigation) != 0 ||
                                                   (branch as IBranch).IsExpandable(relIndex, column));
                        }

                        if (!foundEditableColumn)
                        {
                            // need to do additional search, translate to an up or down search in this particular column
                            column        = newColumn;
                            treeDirection = treeDirection == TreeNavigation.RightColumn ? TreeNavigation.Down : TreeNavigation.Up;
                        }
                    }

                    if (result.Delete)
                    {
                        // we are already focused on an editable column
                        InvalidateItem(CurrentIndex);
                        actionOccurred = true;
                    }
                    else
                    {
                        // search for next matching row/column
                        int oldAbsIndex;
                        while (!foundEditableColumn)
                        {
                            oldAbsIndex = absIndex;
                            if (treeDirection == TreeNavigation.LeftColumn &&
                                column == 0)
                            {
                                absIndex--;
                                if (absIndex >= 0)
                                {
                                    var info = Tree.GetItemInfo(absIndex, 0, false);
                                    column = GetLastColumnIndex(info.Branch, info.Row);
                                }
                            }
                            else if (treeDirection == TreeNavigation.RightColumn &&
                                     column == GetLastColumnIndex((IBranch)branch, relIndex))
                            {
                                absIndex++;
                                column = 0;
                            }
                            else if (result.ColumnType == null)
                            {
                                // search is not restricted to a particular column, so we translate up/down to
                                // left/right search to give a better experience.
                                if (treeDirection == TreeNavigation.Up)
                                {
                                    absIndex--;
                                    treeDirection = TreeNavigation.LeftColumn;

                                    if (absIndex >= 0)
                                    {
                                        // handle jagged column cases
                                        var info = Tree.GetItemInfo(absIndex, 0, false);
                                        if (info.Branch != null)
                                        {
                                            column = GetLastColumnIndex(info.Branch, info.Row);
                                        }
                                    }
                                }
                                else if (treeDirection == TreeNavigation.Down)
                                {
                                    absIndex++;
                                    treeDirection = TreeNavigation.RightColumn;
                                    column        = 0;
                                }
                            }

                            if (absIndex < 0 ||
                                absIndex >= Tree.VisibleItemCount)
                            {
                                break;
                            }

                            var coordinate = new VirtualTreeCoordinate(absIndex, column);
                            if (absIndex == oldAbsIndex)
                            {
                                // if the above didn't result in any navigation, ask the tree to do it itself.
                                coordinate = Tree.GetNavigationTarget(treeDirection, absIndex, column, ColumnPermutation);
                            }

                            if (coordinate.IsValid)
                            {
                                absIndex = coordinate.Row;
                                column   = coordinate.Column;

                                if (oldAbsIndex != absIndex)
                                {
                                    // we've transitioned to a new row, retrieve new row data from the tree.
                                    var info = Tree.GetItemInfo(absIndex, 0, false);

                                    if (result.Local &&
                                        branch != null &&
                                        branch != info.Branch)
                                    {
                                        // stop search if we shouldn't go past current branch
                                        break;
                                    }

                                    branch     = info.Branch as ITreeGridDesignerBranch;
                                    branchType = branch.GetType();
                                    relIndex   = info.Row;
                                }

                                // allow focus on expandable cells or cells that support navigation that are of the appropriate branch type.
                                if (branch != null
                                    &&
                                    (result.BranchType == null || branchType == result.BranchType ||
                                     branchType.IsSubclassOf(result.BranchType))
                                    &&
                                    ((branch.GetValueSupported(relIndex, column)
                                      & TreeGridDesignerValueSupportedStates.SupportsKeyboardNavigation) != 0 ||
                                     (branch as IBranch).IsExpandable(relIndex, column)))
                                {
                                    foundEditableColumn = true;
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    if (foundEditableColumn)
                    {
                        var currentIndex = CurrentIndex;

                        if (absIndex != currentIndex)
                        {
                            if (currentIndex != -1)
                            {
                                // currentIndex may be -1 if we toggled expansion,
                                // but in that case the base control will take care
                                // of the redraw
                                // TODO : is this a bug in the control?  shouldn't selection
                                // be restored after toggling expansion?
                                InvalidateItem(currentIndex);
                            }

                            CurrentIndex   = absIndex;
                            actionOccurred = true;
                        }

                        if (column != CurrentColumn)
                        {
                            CurrentColumn  = column;
                            actionOccurred = true;
                        }
                    }

                    InLabelEdit = inLabelEdit;
                }
                finally
                {
                    BatchDrawItem = false;
                }
            }
            return(actionOccurred);
        }