/// <summary>
        ///     Handles selection and caret changes due to mouse clicks.
        /// </summary>
        private void DoSelectionChangeFromMouse(
            ref VirtualTreeHitInfo hitInfo, bool shiftPressed, bool controlPressed, MouseButtons mouseButton)
        {
            var fireEvent    = false;
            var columnSwitch = RequireColumnSwitchForSelection(ref hitInfo);

            if (columnSwitch)
            {
                SetSelectionColumn(myMouseDownHitInfo.DisplayColumn, false);
                fireEvent = true;
            }

            if (hitInfo.Row != VirtualTreeConstant.NullIndex)
            {
                if (mouseButton == MouseButtons.Right &&
                    IsSelected(hitInfo.Row))
                {
                    // if right button is clicked, and the index is already selected,
                    // we'll just change the caret.
                    if (CaretIndex != hitInfo.Row)
                    {
                        CaretIndex = hitInfo.Row;
                    }
                }
                else
                {
                    if (GetStyleFlag(VTCStyleFlags.ExtendedMultiSelect))
                    {
                        var action = controlPressed ? ModifySelectionAction.Toggle : ModifySelectionAction.Select;
                        SetCurrentExtendedMultiSelectIndex(hitInfo.Row, shiftPressed, controlPressed, action);
                        // SetCurrentExtendedMultiSelectIndex fires SelectionChanged event.
                        fireEvent = false;
                    }
                    else if (GetStyleFlag(VTCStyleFlags.MultiSelect))
                    {
                        SetSelected(hitInfo.Row, !IsSelected(hitInfo.Row) || columnSwitch);
                        CurrentIndex = hitInfo.Row; // CurrentIndex setter fires SelectionChanged event.
                        fireEvent    = false;
                    }
                    else if (!IsSelected(hitInfo.Row))
                    {
                        CurrentIndex = hitInfo.Row; // CurrentIndex setter fires SelectionChanged event.
                        fireEvent    = false;
                    }
                }
            }

            if (fireEvent)
            {
                DoSelectionChanged();
            }
        }
Пример #2
0
 internal VirtualTreeExtendedHitInfo(ref VirtualTreeHitInfo hitInfo, ref ExtraHitInfo extraHitInfo)
 {
     myHitInfo      = hitInfo;
     myExtraHitInfo = extraHitInfo;
 }
Пример #3
0
 public static bool Compare(VirtualTreeHitInfo operand1, VirtualTreeHitInfo operand2)
 {
     Debug.Assert(false); // There is no need to compare these
     return(false);
 }
            public void Activate(ref VirtualTreeHitInfo hit, ref ExtraHitInfo extraInfo, ref Point mousePos, bool immediateActivation)
            {
                var hWnd = Handle.ToInt32();
                if (hWnd == 0)
                {
                    return;
                }

                var ctrlhWnd = Handle;
                NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_ACTIVATE, 0, hWnd);
                if (hit.Row != VirtualTreeConstant.NullIndex)
                {
                    var ti = new NativeMethods.TOOLINFO();
                    ti.SetSize();
                    ti.uId = hWnd;
                    ti.uFlags = NativeMethods.TTF_IDISHWND;
                    ti.rect = NativeMethods.RECT.FromXYWH(
                        extraInfo.ClippedItemRectangle.X,
                        extraInfo.ClippedItemRectangle.Y,
                        extraInfo.ClippedItemRectangle.Width,
                        extraInfo.ClippedItemRectangle.Height);
                    NativeMethods.SendMessage(
                        ctrlhWnd, NativeMethods.TTM_SETDELAYTIME, NativeMethods.TTDT_INITIAL, immediateActivation ? 0 : 250);
                    NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_NEWTOOLRECT, 0, ref ti);
                    NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_ACTIVATE, 1, hWnd);
                    Font = extraInfo.LabelFont;
                    myFormat = extraInfo.LabelFormat;
                    myFullLabelRectangle = extraInfo.FullLabelRectangle;
                    myActivatingMousePos = mousePos;
                }
            }
 /// <summary>
 ///     Helper routine to determine if the column needs to be switched to
 ///     correctly display the selection of an item.
 /// </summary>
 /// <param name="hitInfo">The hitInfo to test</param>
 /// <returns>true if a column change is required to honor the selection request</returns>
 private bool RequireColumnSwitchForSelection(ref VirtualTreeHitInfo hitInfo)
 {
     var retVal = false;
     var selColumn = mySelectionColumn;
     if (hitInfo.DisplayColumn != selColumn)
     {
         if (GetStyleFlag(VTCStyleFlags.MultiSelect) && ExtendSelectionToAnchors)
         {
             if (hitInfo.DisplayColumn == hitInfo.RawColumn)
             {
                 // Single width column, must switch
                 retVal = true;
             }
             else if (!((selColumn >= hitInfo.DisplayColumn && selColumn <= hitInfo.RawColumn) ||
                        (selColumn <= hitInfo.DisplayColumn && selColumn >= hitInfo.RawColumn)))
             {
                 // The selection column is between the hit columns
                 // Note that the only time this does not work is with a blank expansion
                 // that has an offset anchor. However, even in this case, you have to click
                 // on the column, or on opposite sides of the column to make the column switch,
                 // which is still a reasonable behavior.
                 retVal = true;
             }
         }
         else
         {
             retVal = true;
         }
     }
     return retVal;
 }
        /// <summary>
        ///     Control.OnMouseDown override. Handles tree-specific mouse gestures and events.
        /// </summary>
        /// <param name="e">MouseEventArgs</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Clicks == 2)
            {
                var doubleClickArgs = new DoubleClickEventArgs(this, e.Button, e.X, e.Y);
                OnDoubleClick(doubleClickArgs);
                if (doubleClickArgs.Handled)
                {
                    SetStateFlag(VTCStateFlags.CallDefWndProc, false);
                }
            }
            else
            {
                var hitInfo = myMouseDownHitInfo = HitInfo(e.X, e.Y);
                // == OnItemButton is correct here. Ignore OnItemButton if OnBlankItem is also set
                if (e.Button == MouseButtons.Left
                    && 0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemButton))
                {
                    if (myTree.IsExpandable(hitInfo.Row, hitInfo.NativeColumn))
                    {
                        myTree.ToggleExpansion(hitInfo.Row, hitInfo.NativeColumn);
                        SetStateFlag(VTCStateFlags.CallDefWndProc, false);
                        return;
                    }
                }

                if (e.Button == MouseButtons.Left
                    && 0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemStateIcon))
                {
                    // the state icon was clicked
                    ToggleAndSynchronizeState(myMouseDownHitInfo.Row, myMouseDownHitInfo.NativeColumn);
                    SetStateFlag(VTCStateFlags.CallDefWndProc, false);
                    return;
                }

                if (0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnBlankItem)
                    && e.Button != MouseButtons.Right)
                {
                    if (hitInfo.HitTarget != VirtualTreeHitTargets.OnBlankItem)
                    {
                        // This is an anchored blank item, handle it specially.
                        // Hold off on shifting anchor columns until we need to.
                        if (RequireColumnSwitchForSelection(ref hitInfo))
                        {
                            SetSelectionColumn(hitInfo.DisplayColumn, false);
                        }
                        if (GetStyleFlag(VTCStyleFlags.ExtendedMultiSelect))
                        {
                            var isControlPressed = GetStateFlag(VTCStateFlags.MouseButtonDownCtrl);
                            SetCurrentExtendedMultiSelectIndex(
                                hitInfo.Row, GetStateFlag(VTCStateFlags.MouseButtonDownShift), isControlPressed,
                                isControlPressed ? ModifySelectionAction.Toggle : ModifySelectionAction.Select);
                        }
                        else
                        {
                            CurrentIndex = hitInfo.Row;
                        }
                    }
                    SetStateFlag(VTCStateFlags.CallDefWndProc, false);
                    SetStateFlag(VTCStateFlags.StandardLButtonDownProcessing, true);
                }
                    // special handling for right-clicks.  These don't select in a standard list box, we want 
                    // them to select here
                else if (e.Button == MouseButtons.Right)
                {
                    if (myMouseDownHitInfo.Row != -1)
                    {
                        DoSelectionChangeFromMouse(
                            ref hitInfo, GetStateFlag(VTCStateFlags.MouseButtonDownShift), GetStateFlag(VTCStateFlags.MouseButtonDownCtrl),
                            MouseButtons.Right);
                    }
                }
            }

            base.OnMouseDown(e);
        }
Пример #7
0
 internal VirtualTreeExtendedHitInfo(ref VirtualTreeHitInfo hitInfo, ref ExtraHitInfo extraHitInfo)
 {
     myHitInfo = hitInfo;
     myExtraHitInfo = extraHitInfo;
 }
Пример #8
0
 public static bool Compare(VirtualTreeHitInfo operand1, VirtualTreeHitInfo operand2)
 {
     Debug.Assert(false); // There is no need to compare these
     return false;
 }