/// <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); } } }