private string ArgsToText( TVNMA_ActionArgs Args, bool bBefore) { // Deleted node? if (!bBefore && Args.Action == TVNMA_Actions.Delete) { if (Args.DestNode != null) { return string.Format("Action={0}, OldPath=[{1}] CurSelPath=[{2}]", Args.Action.ToString(), Args.Tag as string, Args.DestNode.FullPath); } else { return "Empty!"; } } else { return string.Format("@{0},Action={1},OldPath=[{2}] NewPath[{3}]", Args.SrcNode.Index, Args.Action.ToString(), Args.Tag as string, Args.SrcNode.FullPath); } }
private bool BeforeTVNMA(TVNMA_ActionArgs Args) { switch (Args.Action) { case TVNMA_Actions.Add_Above: Args.TextNew = "New node above - " + Args.TextOld; break; case TVNMA_Actions.Add_Below: Args.TextNew = "New node below - " + Args.TextOld; break; case TVNMA_Actions.Rename: Args.TextNew = Args.TextOld + "*"; break; } Text = ArgsToText(Args, true); Args.Tag = Args.SrcNode.FullPath; return true; }
private bool DoOnBeforeAction(TVNMA_ActionArgs Args) { return OnBeforeAction == null ? true : OnBeforeAction(Args); }
private bool CarryTVNodeAction( TVNMA_ActionArgs Args) { // SrcNode should always be not null if (Args.SrcNode == null) return false; // Capture old title before calling the callback Args.TextOld = Args.SrcNode.Text; // Internal flag allows us to call this function recursively if needed. bool bInternal = Args.Action.HasFlag(TVNMA_Actions.Internal); if (!bInternal && !DoOnBeforeAction(Args)) return false; var tv = Args.SrcNode.TreeView; TreeNode PrevParent = Args.SrcNode.Parent == null ? tv.TopNode : Args.SrcNode.Parent; // Clear the internal flag Args.Action &= ~TVNMA_Actions.Internal; switch (Args.Action) { case TVNMA_Actions.Rename: Args.SrcNode.Text = Args.TextNew; break; case TVNMA_Actions.Add_Both: { // Create new node with the desired title. // (No need to insert the node into the tree since it will be moved.) Args.DestNode = new TreeNode(Args.TextNew); // Move the node above Args.DestNode.MoveAboveOrBelow( Args.SrcNode, bAbove: Args.Action == TVNMA_Actions.Add_Above); break; } case TVNMA_Actions.Add_Above: case TVNMA_Actions.Add_Below: goto case TVNMA_Actions.Add_Both; case TVNMA_Actions.Move_Above: Args.SrcNode.MoveAboveOrBelow( Args.DestNode, bAbove: true); break; case TVNMA_Actions.Move_Below: Args.SrcNode.MoveAboveOrBelow( Args.DestNode, bAbove: false); break; case TVNMA_Actions.Move_Into_Top: Args.SrcNode.MakeChildOf( Args.DestNode, bAppend: false); break; case TVNMA_Actions.Move_Into_Bottom: Args.SrcNode.MakeChildOf( Args.DestNode, bAppend: true); break; case TVNMA_Actions.Indent: Args.SrcNode.Indent(); break; case TVNMA_Actions.UnIndent: Args.SrcNode.UnIndent(); break; case TVNMA_Actions.Delete: { // Elect the new selected node after deleltion // NextNode? Args.DestNode = Args.SrcNode.NextNode; // PrevNode? if (Args.DestNode == null) Args.DestNode = Args.SrcNode.PrevNode; // Parent? if (Args.DestNode == null) Args.DestNode = Args.SrcNode.Parent; // Delete the node Args.SrcNode.Remove(); // Also clear the node reference so the caller knows Args.SrcNode = null; break; } default: return false; } TreeNode VisSrcNode = (Args.Action == TVNMA_Actions.Delete) ? Args.DestNode : Args.SrcNode; if (VisSrcNode != null) { tv.SelectedNode = VisSrcNode; // Set new parent if (VisSrcNode.Parent == null && tv.TopNode != null) tv.TopNode.SetAutoImageIndex(); else VisSrcNode.Parent.SetAutoImageIndex(); } if (PrevParent != null) PrevParent.SetAutoImageIndex(); return bInternal ? true : DoOnAfterAction(Args); }
private void CreateMenuItems() { m_AllActions = TVNMA_Actions.None; if (WantedActions == null) return; // Create all menu items var _acts = new Dictionary<TVNMA_Actions, TVNMA_ActionOptions>(); foreach (var act in WantedActions) { if (bWantMenu) { _acts[act.Action] = act; act.MenuItem = new ToolStripMenuItem() { ShortcutKeys = act.Shortcut, Text = act.MenuText }; } m_AllActions |= act.Action; } if (!bWantMenu) return; if (Menu == null) Menu = new ContextMenuStrip(); m_AllMenuItems = new List<ToolStripItem>(); var AddSep = new Action(() => { m_AllMenuItems.Add(new ToolStripSeparator()); }); // // Assign Ident menu item actions // TVNMA_ActionOptions Opts; if (_acts.TryGetValue(TVNMA_Actions.Indent, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.Indent, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (_acts.TryGetValue(TVNMA_Actions.UnIndent, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.UnIndent, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (m_AllActions.HasFlag(TVNMA_Actions.Indent_Both)) AddSep(); // // Assign Add menu item actions // if (_acts.TryGetValue(TVNMA_Actions.Add_Above, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.Add_Above, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (_acts.TryGetValue(TVNMA_Actions.Add_Below, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.Add_Below, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (m_AllActions.HasFlag(TVNMA_Actions.Add_Both)) AddSep(); // // Assign Move menu item actions // if (_acts.TryGetValue(TVNMA_Actions.Move_Above, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { var Args = new TVNMA_ActionArgs() { Action = TVNMA_Actions.Move_Above, SrcNode = tv.SelectedNode, DestNode = tv.SelectedNode.PrevNode }; if (Args.DestNode != null) CarryTVNodeAction(Args); }); m_AllMenuItems.Add(Opts.MenuItem); } if (_acts.TryGetValue(TVNMA_Actions.Move_Below, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { var Args = new TVNMA_ActionArgs() { Action = TVNMA_Actions.Move_Below, SrcNode = tv.SelectedNode, DestNode = tv.SelectedNode.NextNode }; if (Args.DestNode != null) CarryTVNodeAction(Args); }); m_AllMenuItems.Add(Opts.MenuItem); } if (m_AllActions.HasFlag(TVNMA_Actions.Move_Both)) AddSep(); // // Add Rename/Delete // if (_acts.TryGetValue(TVNMA_Actions.Rename, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.Rename, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (_acts.TryGetValue(TVNMA_Actions.Delete, out Opts)) { Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev) { CarryTVNodeAction(new TVNMA_ActionArgs() { Action = TVNMA_Actions.Delete, SrcNode = tv.SelectedNode }); }); m_AllMenuItems.Add(Opts.MenuItem); } if (m_AllActions.HasFlag(TVNMA_Actions.RenOrDel)) AddSep(); // // Add all the menu items // if (m_AllMenuItems[m_AllMenuItems.Count - 1] is ToolStripSeparator) m_AllMenuItems.RemoveAt(m_AllMenuItems.Count - 1); foreach (var mi in m_AllMenuItems) Menu.Items.Add(mi); tv.ContextMenuStrip = Menu; }
private void SetupDragDropHandlers() { if (!bWantDragDrop) return; tv.AllowDrop = true; // // ItemDrag // tv.ItemDrag += new ItemDragEventHandler(delegate (object sender, ItemDragEventArgs e) { tv.DoDragDrop( e.Item, DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link); }); // // DragEnter // tv.DragEnter += new DragEventHandler(delegate (object sender, DragEventArgs e) { if (e.Data.GetDataPresent(TV_NODE)) { e.Effect = GetDragEffectFromKeyState(e.KeyState); } else { e.Effect = DragDropEffects.None; } }); // // DragOver // tv.DragOver += new DragEventHandler(delegate (object sender, DragEventArgs e) { if (!e.Data.GetDataPresent(TV_NODE)) return; var treeView = sender as System.Windows.Forms.TreeView; Point pt = treeView.PointToClient(new Point(e.X, e.Y)); TreeNode DestTreeNode = treeView.GetNodeAt(pt); if (DestTreeNode == null) return; TreeNode SrcTreeNode = e.Data.GetData(TV_NODE) as TreeNode; // Select the destination node treeView.SelectedNode = DestTreeNode; // Make sure we are not going to drop the src node into any of its parent nodes var parent = DestTreeNode; while (parent != null) { if (parent == SrcTreeNode) { e.Effect = DragDropEffects.None; return; } // Walk up the tree to figure out that the destination node is not inside its parent parent = parent.Parent; } if (nAutoExpandMS > 0) { // If the destination node has changed, then reset the stopwatch if (m_LastDragOverDestTreeNode != DestTreeNode) { m_DragOverAutoExpandStopWatch.Restart(); } else { // Enough time elapsed? User's intent to open this node if (m_DragOverAutoExpandStopWatch.ElapsedMilliseconds > nAutoExpandMS) DestTreeNode.Expand(); } // Remember the last node m_LastDragOverDestTreeNode = DestTreeNode; } e.Effect = GetDragEffectFromKeyState(e.KeyState); }); // // DragDrop // tv.DragDrop += new DragEventHandler(delegate (object sender, DragEventArgs e) { if (!e.Data.GetDataPresent(TV_NODE)) { e.Effect = DragDropEffects.None; return; } var tv = sender as System.Windows.Forms.TreeView; Point pt = tv.PointToClient(new Point(e.X, e.Y)); TreeNode DestTreeNode = tv.GetNodeAt(pt); TreeNode SrcTreeNode = e.Data.GetData(TV_NODE) as TreeNode; // Remember the source node's parent (before the action takes place). // We need this so we can properly update its image indexes. // For example, if we move out its last child, then it becomes a regular node. var SrcParent = SrcTreeNode.Parent; // Create a TreeNode Action var Args = new TVNMA_ActionArgs() { SrcNode = SrcTreeNode, DestNode = DestTreeNode }; // Convert KeyStates into an elaborate action if (m_bDragInto && m_bDragAbove) { Args.Action = TVNMA_Actions.Move_Into_Top; } else if (m_bDragInto && !m_bDragAbove) { Args.Action = TVNMA_Actions.Move_Into_Bottom; } else if (m_bDragAbove) { Args.Action = TVNMA_Actions.Move_Above; } else if (m_bDragInto) { Args.Action = TVNMA_Actions.Move_Into_Bottom; } // No action intended yet, let's try to guess user's intent if (Args.Action == TVNMA_Actions.None) { // Must be moving to a parent node if (DestTreeNode.IsExpanded) { Args.Action = TVNMA_Actions.Move_Into_Bottom; } // Just a regular node, let's just move above else { Args.Action = TVNMA_Actions.Move_Above; } } CarryTVNodeAction(Args); DestTreeNode.SetAutoImageIndex(); if (SrcParent != null) SrcParent.SetAutoImageIndex(); }); // // BeforeCollapse // tv.BeforeCollapse += new TreeViewCancelEventHandler(delegate (object sender, TreeViewCancelEventArgs e) { e.Node.SetAllImageIndex(TVNMA_NodeIconIndex.Closed); }); // // BeforeExpand // tv.BeforeExpand += new TreeViewCancelEventHandler(delegate (object sender, TreeViewCancelEventArgs e) { e.Node.SetAllImageIndex(TVNMA_NodeIconIndex.Opened); }); }
private bool AfterTVNMA(TVNMA_ActionArgs Args) { Text = ArgsToText(Args, false); return true; }