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;
        }
Exemplo n.º 2
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);
        }