private void SetupEventhandlers() { adConfigMonitor.Changed += (object o, FileSystemEventArgs e) => { if (e.FullPath == adConfigFileName && (DateTime.Now.Ticks - lastConfigUpdate > 500000)) { lastConfigUpdate = DateTime.Now.Ticks; this.Invoke((MethodInvoker) delegate { LoadAddressBook(); }); } }; TreeViewItems.MouseDoubleClick += (object o, MouseEventArgs e) => { TreeNode n = TreeViewItems.GetNodeAt(e.Location); if (n == null || n.Tag is Group) { return; } Connect(); }; TreeViewItems.MouseDown += (object o, MouseEventArgs e) => { TreeNode n = TreeViewItems.GetNodeAt(e.Location); if (n == null || e.Button != MouseButtons.Right) { return; } TreeViewItems.SelectedNode = n; }; TreeViewItems.MouseUp += delegate { isDragging = false; }; TreeViewItems.DragLeave += delegate { isDragging = false; }; TreeViewItems.DragEnter += delegate { isDragging = true; }; TreeViewItems.AfterSelect += delegate { selectedNode = TreeViewItems.SelectedNode; if (selectedNode == null) { return; } HandleNodeSelected(selectedNode); }; TreeViewItems.AfterLabelEdit += (object o, NodeLabelEditEventArgs e) => { if (e.Label != null && e.Label != "") { ((ADItem)e.Node.Tag).Name = e.Label; SaveSettings(true); } }; TreeViewItems.BeforeLabelEdit += (object o, NodeLabelEditEventArgs e) => e.CancelEdit = (e.Node.Parent == null); TreeViewItems.ItemDrag += (object o, ItemDragEventArgs e) => { selectedNode = (TreeNode)e.Item; if (e.Button == MouseButtons.Left) { isDragging = true; TreeViewItems.SelectedNode = selectedNode; TreeViewItems.DoDragDrop(selectedNode, DragDropEffects.Move); } }; TreeViewItems.DragOver += (object o, DragEventArgs e) => { draggingLocation = TreeViewItems.PointToClient(new Point(e.X, e.Y)); dragginOverNode = TreeViewItems.GetNodeAt(draggingLocation); if (dragginOverNode == null || dragginOverNode.Tag is Item) { e.Effect = DragDropEffects.None; } else { e.Effect = e.AllowedEffect; } }; TreeViewItems.DragDrop += (object o, DragEventArgs e) => { dragginOverNode = TreeViewItems.GetNodeAt(TreeViewItems.PointToClient(new Point(e.X, e.Y))); if (dragginOverNode != null) { Group tg = (Group)dragginOverNode.Tag; string nodeText = selectedNode.Text; if (selectedNode.Tag is Item si) { ((Group)si.Parent).Items.Remove(si); tg.Items.Add((Item)si.Clone(tg)); } else { Group sg = (Group)selectedNode.Tag; ((Group)sg.Parent).Groups.Remove(sg); tg.Groups.Add((Group)sg.Clone(sg)); } SaveSettings(false); SelectNode(TreeViewItems.Nodes, nodeText); } }; ConnectToolStripMenuItem.Click += delegate { Connect(); }; AddItemToolStripMenuItem.Click += delegate { AddItem(); }; AddGroupToolStripMenuItem.Click += delegate { AddGroup(); }; RenameToolStripMenuItem.Click += delegate { selectedNode.BeginEdit(); }; DeleteToolStripMenuItem.Click += delegate { DeleteItem(); }; TextBoxDescription.TextChanged += delegate { if (!ignoreTextBoxEvents) { ((Item)selectedNode.Tag).Description = TextBoxDescription.Text; } }; LinkLabelConnect.Click += delegate { Connect(); }; this.FormClosing += delegate { abortThreads = true; while (draggingMonitor.ThreadState == System.Threading.ThreadState.Background) { Thread.Sleep(100); } adConfigMonitor.Dispose(); SaveSettings(true); }; this.KeyDown += (object o, KeyEventArgs e) => { switch (e.KeyCode) { case Keys.F2: if (this.ActiveControl == TreeViewItems) { selectedNode?.BeginEdit(); } break; case Keys.Enter: Connect(); // Avoid the freaking bell... e.Handled = true; e.SuppressKeyPress = true; break; case Keys.Delete: if (this.ActiveControl == TreeViewItems) { DeleteItem(); } break; } }; TextBoxFilter.TextChanged += (object o, EventArgs e) => filterTimer.Change(500, Timeout.Infinite); }