Ejemplo n.º 1
0
        /// <summary>
        ///     Switch the selection column. For multiselect, the behavior is highly dependent on the
        ///     the ColumnSelectionTransferAction property and the prior state of the permutation, if
        ///     the permutation is being reordered
        /// </summary>
        /// <param name="column">The new selection column</param>
        /// <param name="oldPermutation">The old column permuation</param>
        /// <param name="fireEvents">True if this routine should fire selection events</param>
        private void SetSelectionColumn(int column, ColumnPermutation oldPermutation, bool fireEvents)
        {
            Debug.Assert(oldPermutation != null || column != mySelectionColumn);
            var iCaret = CurrentIndex;

            DismissLabelEdit(false, false);
            var oldColumn = mySelectionColumn;

            mySelectionColumn = column;

            if (GetStyleFlag(VTCStyleFlags.MultiSelect))
            {
                switch (myColumnSelectionAction)
                {
                case ColumnSelectionTransferAction.PreserveNonBlankCells:
                    SetSelectionColumn_PreserveBasic(oldColumn, oldPermutation, column, false, fireEvents);
                    break;

                case ColumnSelectionTransferAction.PreserveAnchoredCells:
                    SetSelectionColumn_PreserveBasic(oldColumn, oldPermutation, column, true, fireEvents);
                    break;

                case ColumnSelectionTransferAction.PreserveSharedAnchors:
                    SetSelectionColumn_PreserveAnchors(oldColumn, oldPermutation, column, false, fireEvents);
                    break;

                case ColumnSelectionTransferAction.PreserveSharedAnchorsOnly:
                    SetSelectionColumn_PreserveAnchors(oldColumn, oldPermutation, column, true, fireEvents);
                    break;

                case ColumnSelectionTransferAction.ClearSelectedRows:
                    SetSelectionColumn_Clear(fireEvents);
                    break;
                }
            }
            else if (iCaret != -1 && fireEvents)
            {
                CurrentIndex = iCaret;
            }

            if (oldColumn != mySelectionColumn)
            {
                // This may cause a focus change, because the caret moves to a different column.
                if (!GetStateFlag(VTCStateFlags.RestoringSelection) &&
                    VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectFocus, this) &&
                    Focused)
                {
                    VirtualTreeAccEvents.Notify(
                        VirtualTreeAccEvents.eventObjectFocus, CurrentIndex,
                        CurrentColumn, this);
                }

                // ensure newly selected column is scrolled into view.
                if (HasHorizontalScrollBar)
                {
                    ScrollColumnIntoView(CurrentColumn);
                }

                // make sure we invalidate the caret item
                if (CurrentIndex != VirtualTreeConstant.NullIndex)
                {
                    InvalidateItem(CurrentIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate);
                }
            }
        }
        /// <summary>
        ///     Fires WinEvents for given selection change.
        /// </summary>
        private void FireWinEventsForSelection(bool extendFromAnchor, bool preserveSelection, ModifySelectionAction caretAction)
        {
            if (GetStateFlag(VTCStateFlags.RestoringSelection))
            {
                return; // no events if we're restoring selection.
            }

            if (SelectionCount == 1)
            {
                // if there's currently only one thing selected, we know we should fire a regular selection event.
                if (VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectSelection, this))
                {
                    VirtualTreeAccEvents.Notify(
                        VirtualTreeAccEvents.eventObjectSelection, CurrentIndex,
                        CurrentColumn, this);
                }
            }
            else if (extendFromAnchor)
            {
                if (VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectSelectionWithin, this))
                {
                    // we extended selection from the anchor position, this constitutes a significant change in selection
                    // state, so we fire selection within from the tree control, and let clients query us for the result.
                    // UNDONE: querying currently won't work because we need a way to return an IEnumVariant from IAccessible::get_accSelection.
                    // We just fire selection for the caret instead.
                    // VirtualTreeAccEvents.Notify(VirtualTreeAccEvents.eventObjectSelectionWithin, VirtualTreeConstant.NullIndex,
                    //								 VirtualTreeConstant.NullIndex, this);
                    VirtualTreeAccEvents.Notify(
                        VirtualTreeAccEvents.eventObjectSelection, CurrentIndex,
                        CurrentColumn, this);
                }
            }
            else if (preserveSelection)
            {
                // we're preserving an original selection, which means that we fire either an add or a remove,
                // depending on what happened to the caret
                switch (caretAction)
                {
                case ModifySelectionAction.Select:
                    if (VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectSelectionAdd, this))
                    {
                        VirtualTreeAccEvents.Notify(
                            VirtualTreeAccEvents.eventObjectSelectionAdd, CurrentIndex,
                            CurrentColumn, this);
                    }
                    break;

                case ModifySelectionAction.Clear:
                    if (VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectSelectionRemove, this))
                    {
                        VirtualTreeAccEvents.Notify(
                            VirtualTreeAccEvents.eventObjectSelectionRemove, CurrentIndex,
                            CurrentColumn, this);
                    }
                    break;

                case ModifySelectionAction.Toggle:
                    if (IsSelected(CaretIndex))
                    {
                        goto case ModifySelectionAction.Select;
                    }
                    else
                    {
                        goto case ModifySelectionAction.Clear;
                    }

                case ModifySelectionAction.None:
                    // Caret position didn't change, but selection still changed overall.  This happens, for instance,
                    // during cross-column selection transfer.  We would ideally fire selection within here, for now
                    // we just fire selection at the caret position anyway.
                    if (VirtualTreeAccEvents.ShouldNotify(VirtualTreeAccEvents.eventObjectSelectionWithin, this))
                    {
                        //VirtualTreeAccEvents.Notify(VirtualTreeAccEvents.eventObjectSelectionWithin, VirtualTreeConstant.NullIndex,
                        //								VirtualTreeConstant.NullIndex, this);
                        VirtualTreeAccEvents.Notify(
                            VirtualTreeAccEvents.eventObjectSelection, CurrentIndex,
                            CurrentColumn, this);
                    }
                    break;
                }
            }
        }