Index: Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.Designer.cs =================================================================== diff -u -r3a2348c5fe73aa8d0979407c45ce70519288cf3f -re3b933da9f371c4139223a5d8f6430558a3c4338 --- Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 3a2348c5fe73aa8d0979407c45ce70519288cf3f) +++ Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision e3b933da9f371c4139223a5d8f6430558a3c4338) @@ -61,15 +61,6 @@ } /// - /// Looks up a localized string similar to Fout tijdens slepen/neerzetten: {0}.. - /// - internal static string TreeViewControl_DragDrop_Error_during_drag_drop_0_ { - get { - return ResourceManager.GetString("TreeViewControl_DragDrop_Error_during_drag_drop_0_", resourceCulture); - } - } - - /// /// Looks up a localized string similar to Weet u zeker dat u het volgende element wilt verwijderen: {0}. /// internal static string TreeViewControl_Remove_Are_you_sure_you_want_to_remove_the_following_item_0_ { @@ -86,5 +77,14 @@ return ResourceManager.GetString("TreeViewControl_Remove_The_selected_item_cannot_be_removed", resourceCulture); } } + + /// + /// Looks up a localized string similar to Het geselecteerde element kan niet worden hernoemd.. + /// + internal static string TreeViewControl_The_selected_item_cannot_be_renamed { + get { + return ResourceManager.GetString("TreeViewControl_The_selected_item_cannot_be_renamed", resourceCulture); + } + } } } Index: Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.resx =================================================================== diff -u -r3a2348c5fe73aa8d0979407c45ce70519288cf3f -re3b933da9f371c4139223a5d8f6430558a3c4338 --- Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.resx (.../Resources.resx) (revision 3a2348c5fe73aa8d0979407c45ce70519288cf3f) +++ Core/Common/src/Core.Common.Controls.TreeView/Properties/Resources.resx (.../Resources.resx) (revision e3b933da9f371c4139223a5d8f6430558a3c4338) @@ -117,13 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Fout tijdens slepen/neerzetten: {0}. - Het geselecteerde element kan niet worden verwijderd. Weet u zeker dat u het volgende element wilt verwijderen: {0} + + Het geselecteerde element kan niet worden hernoemd. + \ No newline at end of file Index: Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs =================================================================== diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -re3b933da9f371c4139223a5d8f6430558a3c4338 --- Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71) +++ Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision e3b933da9f371c4139223a5d8f6430558a3c4338) @@ -43,10 +43,9 @@ public event EventHandler NodeUpdated; // TODO; Way to explicit! public event EventHandler DataDeleted; // TODO; Way to explicit! - private static readonly ILog Log = LogManager.GetLogger(typeof(TreeViewControl)); - private readonly ICollection treeNodeInfos = new HashSet(); + private static readonly ILog log = LogManager.GetLogger(typeof(TreeViewControl)); private readonly Dictionary tagTypeTreeNodeInfoLookup = new Dictionary(); - private readonly int maximumTextLength = 259; + private const int maximumTextLength = 259; private readonly Dictionary treeNodeObserverLookup = new Dictionary(); private object data; private int dropAtLocation; @@ -55,6 +54,9 @@ private TreeNode nodeDropTarget; private TreeNode lastPlaceholderNode; private Graphics placeHolderGraphics; + private const string stateImageLocationString = "StateImage"; + private const int uncheckedCheckBoxStateImageIndex = 0; + private const int checkedCheckBoxStateImageIndex = 1; public TreeViewControl() { @@ -127,7 +129,6 @@ /// The to register. public void RegisterTreeNodeInfo(TreeNodeInfo treeNodeInfo) { - treeNodeInfos.Add(treeNodeInfo); tagTypeTreeNodeInfoLookup[treeNodeInfo.TagType] = treeNodeInfo; } @@ -144,7 +145,7 @@ if (treeNode != null) { - treeNode.BeginEdit(); + Rename(treeNode); } } @@ -169,7 +170,7 @@ { var treeNode = GetNodeByTag(dataObject); - return treeNode != null && treeNode.Nodes.OfType().Any(); + return treeNode != null && treeNode.Nodes.Count > 0; } public void CollapseAllNodesForData(object dataObject) @@ -201,22 +202,34 @@ { var treeNode = GetNodeByTag(dataObject); - return treeNode != null ? treeNode.FullPath : ""; + return treeNode != null ? treeNode.FullPath : null; } private bool CanRename(TreeNode treeNode) { var treeNodeInfo = GetTreeNodeInfoForData(treeNode.Tag); - var parentTag = treeNode.Parent != null ? treeNode.Parent.Tag : null; + var parentTag = GetParentTag(treeNode); return treeNodeInfo.CanRename != null && treeNodeInfo.CanRename(treeNode.Tag, parentTag); } + private void Rename(TreeNode treeNode) + { + if (!CanRename(treeNode)) + { + MessageBox.Show(Resources.TreeViewControl_The_selected_item_cannot_be_renamed, BaseResources.Confirm, MessageBoxButtons.OK); + return; + } + + treeNode.BeginEdit(); + } + private bool CanRemove(TreeNode treeNode) { var treeNodeInfo = GetTreeNodeInfoForData(treeNode.Tag); + var parentTag = GetParentTag(treeNode); - return treeNodeInfo.CanRemove != null && treeNodeInfo.CanRemove(treeNode.Tag, treeNode.Parent != null ? treeNode.Parent.Tag : null); + return treeNodeInfo.CanRemove != null && treeNodeInfo.CanRemove(treeNode.Tag, parentTag); } private void Remove(TreeNode treeNode) @@ -237,7 +250,9 @@ if (treeNodeInfo.OnNodeRemoved != null) { - treeNodeInfo.OnNodeRemoved(treeNode.Tag, treeNode.Parent != null ? treeNode.Parent.Tag : null); + var parentTag = GetParentTag(treeNode); + + treeNodeInfo.OnNodeRemoved(treeNode.Tag, parentTag); } OnNodeDataDeleted(treeNode); @@ -247,7 +262,7 @@ { treeNode.Collapse(); - foreach (var childNode in treeNode.Nodes.OfType()) + foreach (TreeNode childNode in treeNode.Nodes) { CollapseAll(childNode); } @@ -257,7 +272,7 @@ { treeNode.Expand(); - foreach (var childNode in treeNode.Nodes.OfType()) + foreach (TreeNode childNode in treeNode.Nodes) { ExpandAll(childNode); } @@ -284,9 +299,7 @@ /// The corresponding the provided node data or null if not found. private TreeNode GetNodeByTag(object nodeData) { - var node = treeView.Nodes.Count > 0 ? GetNodeByTag(treeView.Nodes[0], nodeData) : null; - - return node; + return treeView.Nodes.Count > 0 ? GetNodeByTag(treeView.Nodes[0], nodeData) : null; } private static TreeNode GetNodeByTag(TreeNode rootNode, object tag) @@ -297,7 +310,7 @@ } return rootNode.Nodes - .OfType() + .Cast() .Select(n => GetNodeByTag(n, tag)) .FirstOrDefault(node => node != null); } @@ -346,7 +359,7 @@ treeNode.Checked = !treeNode.Checked; treeView.AfterCheck += TreeViewAfterCheck; } - treeNode.StateImageIndex = treeNode.Checked ? 1 : 0; + treeNode.StateImageIndex = treeNode.Checked ? checkedCheckBoxStateImageIndex : uncheckedCheckBoxStateImageIndex; } OnNodeUpdated(treeNode); @@ -436,7 +449,7 @@ treeNodeObserverLookup[treeNode].Dispose(); treeNodeObserverLookup.Remove(treeNode); - foreach (var childNode in treeNode.Nodes.OfType()) + foreach (TreeNode childNode in treeNode.Nodes) { RemoveTreeNodeFromLookupRecursively(childNode); } @@ -466,8 +479,8 @@ private void RefreshChildNodes(TreeNode treeNode, TreeNodeInfo treeNodeInfo) { var newTreeNodes = new Dictionary(); - var outdatedTreeNodes = treeNode.Nodes.OfType().ToList(); - var currentTreeNodesPerTag = treeNode.Nodes.OfType().ToList().ToDictionary(ctn => ctn.Tag, ctn => ctn); + var outdatedTreeNodes = treeNode.Nodes.Cast().ToList(); + var currentTreeNodesPerTag = treeNode.Nodes.Cast().ToList().ToDictionary(ctn => ctn.Tag, ctn => ctn); var newChildNodeObjects = treeNodeInfo.ChildNodeObjects != null ? treeNodeInfo.ChildNodeObjects(treeNode.Tag) : new object[0]; @@ -517,6 +530,27 @@ } } + private static object GetParentTag(TreeNode treeNode) + { + return treeNode.Parent != null ? treeNode.Parent.Tag : null; + } + + private void OnNodeUpdated(TreeNode treeNode) + { + if (NodeUpdated != null) + { + NodeUpdated(treeNode, EventArgs.Empty); + } + } + + private void OnNodeDataDeleted(TreeNode node) + { + if (DataDeleted != null) + { + DataDeleted(this, new TreeNodeDataDeletedEventArgs(node.Tag)); + } + } + # region Nested types private class TreeNodeObserver : IDisposable, IObserver @@ -583,7 +617,9 @@ var treeNodeInfo = GetTreeNodeInfoForData(e.Node.Tag); if (treeNodeInfo.OnNodeChecked != null) { - treeNodeInfo.OnNodeChecked(e.Node.Tag, e.Node.Parent != null ? e.Node.Parent.Tag : null); + var parentTag = GetParentTag(e.Node); + + treeNodeInfo.OnNodeChecked(e.Node.Tag, parentTag); } } @@ -607,16 +643,17 @@ } case Keys.F2: // Start editing the label of the selected node { - selectedNode.BeginEdit(); + Rename(selectedNode); break; } case Keys.Apps: // If implemented, show the context menu of the selected node { var treeNodeInfo = GetTreeNodeInfoForData(selectedNode.Tag); + var parentTag = GetParentTag(selectedNode); // Update the context menu (relevant in case of keyboard navigation in the tree view) selectedNode.ContextMenuStrip = treeNodeInfo.ContextMenuStrip != null - ? treeNodeInfo.ContextMenuStrip(selectedNode.Tag, selectedNode.Parent != null ? selectedNode.Parent.Tag : null, this) + ? treeNodeInfo.ContextMenuStrip(selectedNode.Tag, parentTag, this) : null; if (treeView.ContextMenu != null && selectedNode.ContextMenuStrip != null) @@ -630,7 +667,7 @@ } case Keys.Enter: // Perform the same action as on double click { - OnTreeNodeDoubleClick(); + OnDataDoubleClick(); break; } @@ -652,13 +689,13 @@ } } - if (keyEventArgs.KeyData == (Keys.Control | Keys.Shift | Keys.Right)) // Expand all tree nodes + if (keyEventArgs.KeyData == (Keys.Control | Keys.Shift | Keys.Right)) // Expand all child nodes of the selected tree node { ExpandAll(selectedNode); selectedNode.EnsureVisible(); } - if (keyEventArgs.KeyData == (Keys.Control | Keys.Shift | Keys.Left)) // Collapse all tree nodes + if (keyEventArgs.KeyData == (Keys.Control | Keys.Shift | Keys.Left)) // Collapse all child nodes of the selected tree node { CollapseAll(selectedNode); selectedNode.EnsureVisible(); @@ -676,13 +713,15 @@ var treeNodeInfo = GetTreeNodeInfoForData(clickedNode.Tag); - if ((e.Button & MouseButtons.Right) != 0) + if (e.Button.HasFlag(MouseButtons.Right)) { treeView.SelectedNode = clickedNode; + var parentTag = GetParentTag(clickedNode); + // Update the context menu clickedNode.ContextMenuStrip = treeNodeInfo.ContextMenuStrip != null - ? treeNodeInfo.ContextMenuStrip(clickedNode.Tag, clickedNode.Parent != null ? clickedNode.Parent.Tag : null, this) + ? treeNodeInfo.ContextMenuStrip(clickedNode.Tag, parentTag, this) : null; return; @@ -697,15 +736,15 @@ private bool IsOnCheckBox(Point point) { - return treeView.HitTest(point).Location.ToString() == "StateImage"; + return treeView.HitTest(point).Location.ToString() == stateImageLocationString; } private void TreeViewDoubleClick(object sender, EventArgs e) { - OnTreeNodeDoubleClick(); + OnDataDoubleClick(); } - private void OnTreeNodeDoubleClick() + private void OnDataDoubleClick() { if (DataDoubleClick != null) { @@ -733,12 +772,9 @@ } // Handle dragged items which were originally higher up in the tree under the same parent (all indices shift by one) - if (e.Effect.Equals(DragDropEffects.Move) && nodeDragging.Parent == nodeDropTarget && nodeOver.Index > nodeDragging.Index) + if (e.Effect.Equals(DragDropEffects.Move) && nodeDragging.Parent == nodeDropTarget && nodeOver.Index > nodeDragging.Index && dropAtLocation > 0) { - if (dropAtLocation > 0) - { - dropAtLocation--; - } + dropAtLocation--; } // Ensure the drop location is never < 0 @@ -748,28 +784,20 @@ } var treeNodeInfo = GetTreeNodeInfoForData(nodeDropTarget.Tag); + var previousParentNode = nodeDragging.Parent; - try - { - var previousParentNode = nodeDragging.Parent; + previousParentNode.Nodes.Remove(nodeDragging); + nodeDropTarget.Nodes.Insert(dropAtLocation, nodeDragging); - previousParentNode.Nodes.Remove(nodeDragging); - nodeDropTarget.Nodes.Insert(dropAtLocation, nodeDragging); + // Ensure the dragged node is visible afterwards + nodeDragging.EnsureVisible(); - // Ensure the dragged node is visible afterwards - nodeDragging.EnsureVisible(); + // Restore any lost selection + treeView.SelectedNode = nodeDragging; - // Restore any lost selection - treeView.SelectedNode = nodeDragging; - - if (treeNodeInfo.OnDrop != null) - { - treeNodeInfo.OnDrop(nodeDragging.Tag, nodeDragging.Parent.Tag, previousParentNode.Tag, ToDragOperation(e.Effect), dropAtLocation, this); - } - } - catch (Exception ex) + if (treeNodeInfo.OnDrop != null) { - Log.Error(string.Format(Resources.TreeViewControl_DragDrop_Error_during_drag_drop_0_, ex.Message)); + treeNodeInfo.OnDrop(nodeDragging.Tag, nodeDragging.Parent.Tag, previousParentNode.Tag, ToDragOperation(e.Effect), dropAtLocation, this); } } @@ -815,8 +843,8 @@ return; } - // Determine whether ot not the node can be dropped based on the allowed operations. - // A node can also be a valid drop traget if it is the root item (nodeDragging.Parent == null). + // Determine whether or not the node can be dropped based on the allowed operations. + // A node can also be a valid drop target if it is the root item (nodeDragging.Parent == null). var dragOperations = treeNodeInfo.CanDrop != null ? treeNodeInfo.CanDrop(nodeDragging.Tag, nodeDropTarget.Tag, allowedOperations) : DragOperations.None; @@ -838,9 +866,10 @@ // gather allowed effects for the current item. var sourceNode = (TreeNode) e.Item; var treeNodeInfo = GetTreeNodeInfoForData(sourceNode.Tag); + var parentTag = GetParentTag(sourceNode); DragOperations dragOperation = treeNodeInfo.CanDrag != null - ? treeNodeInfo.CanDrag(sourceNode.Tag, sourceNode.Parent != null ? sourceNode.Parent.Tag : null) + ? treeNodeInfo.CanDrag(sourceNode.Tag, parentTag) : DragOperations.None; DragDropEffects effects = ToDragDropEffects(dragOperation); @@ -1023,25 +1052,5 @@ } # endregion - - # region Event handling - - private void OnNodeUpdated(TreeNode treeNode) - { - if (NodeUpdated != null) - { - NodeUpdated(treeNode, EventArgs.Empty); - } - } - - private void OnNodeDataDeleted(TreeNode node) - { - if (DataDeleted != null) - { - DataDeleted(this, new TreeNodeDataDeletedEventArgs(node.Tag)); - } - } - - # endregion } } \ No newline at end of file