/// <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);
        }
        /// <summary>
        ///     Overriden to run the default action specified by the currently selected branch.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDoubleClick(DoubleClickEventArgs e)
        {
            if (e.HitInfo.HitTarget == VirtualTreeHitTargets.OnItemIcon)
            {
                var branch = e.ItemInfo.Branch as ITreeGridDesignerBranch;

                if (branch != null
                    && Site != null
                    && e.ItemInfo.Row != -1)
                {
                    if (DoDefaultAction(branch, e.ItemInfo.Row))
                    {
                        return;
                    }
                }
            }

            base.OnDoubleClick(e);
        }
 /// <summary>
 ///     Called when an item is double-clicked
 /// </summary>
 /// <param name="e">VirtualTreeControl specific DoubleClickEventArgs</param>
 protected virtual void OnDoubleClick(DoubleClickEventArgs e)
 {
     var handler = Events[EVENT_DOUBLECLICK] as DoubleClickEventHandler;
     if (handler != null)
     {
         handler(this, e);
     }
     if (!e.Handled
         && myTree != null
         && e.Button == MouseButtons.Left)
     {
         var hitInfo = e.HitInfo;
         if (0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItem))
         {
             var itemInfo = e.ItemInfo;
             if (0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemStateIcon))
             {
                 // Treat a double click as two single clicks if applied directly to
                 // the state icon.
                 ToggleAndSynchronizeState(hitInfo.Row, hitInfo.NativeColumn);
             }
             else if (itemInfo.Expandable)
             {
                 myTree.ToggleExpansion(hitInfo.Row, hitInfo.NativeColumn);
             }
             else if (myStateImageList != null)
             {
                 // Just toggle here, don't synchronize. This behavior is consisten
                 // with the standard ListView control. The synchronization is hard
                 // for the user and code to coordinate because the single click just
                 // toggled the selection state.
                 myTree.ToggleState(hitInfo.Row, hitInfo.NativeColumn);
             }
         }
         else if (0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemButton))
         {
             // avoid calling the DefWndProc if the click was on the button, because this
             // causes scrolling to the selected index, which may not be the one double-clicked on.
             SetStateFlag(VTCStateFlags.CallDefWndProc, false);
         }
     }
 }