/// If there is no special explanation, the technical articles published by myself are original. Please indicate the source and include this statement.
/// Author: 9CBS screen name alias88, e-mail:
Alias88@163.com
QQ: 63343
Using system;
Using system.componentmodel;
Using system.collections;
Using system.diagnostics;
Using system.drawing;
Using system.windows.forms;
Using system.data;
Namespace UPLibrary.upControls
{
///
// / Implement the drag and drop operation processing, and the addition and removal of each node can raise the TreeView of the event.
/// summary>
Public class updreeViewBase: System.Windows.Forms.treeView
{
Private system.componentmodel.Container Components = NULL;
Private treenode_dragnode;
Private bool _movenode = false;
Private bool _copyNode = false;
Private bool _candropdrag = false;
///
/// Delete the node event handle (sender is a parent node or empty, E.Node is sub-node)
/// summary>
Public Delegate Void NodendeleteHandler (Object Sender, Uplibrary.upControls.treenodeEventArgs E);
///
/// Add a node event handle (sender is a parent node or empty, E.Node is sub-node)
/// summary>
Public Delegate Void Nodeddhandler (Object Sender);
///
/// Browse the child node event handle between delete or add nodes (Sender is the parent node or empty, E.Node is the sub-node)
/// summary>
Public Delegate Void BrowseTreenodeseeventHandler (Object Sender, TreenodeEventArgs E);
///
/// Change the parent node event handle in the drag and drop operation (sender is a parent node or empty, E.Node is sub-node)
/// summary>
Public Delegate Void ParentChangByDrapdrophandler (Object Sender, TreenodeEventArgs E);
[Description ("This event occurs before the parent of the node in drag and drop")]
Public Event ParentChangBydrapdrophandler ParentChangingBydrapdrop;
[Description ("This event happens after the parent of the node" in the drag and drop operation ")]
Public Event ParentChangBydrapdrophandler ParentChangeDByDrapdrop;
[Description ("" The node represented by Sender will be removed, usually after the moving drag and drop operation, or the tree has occurred after the tree is loaded ")]
Public Event NodendeleTehandler Nodendelan;
[Description ("The nodes represented by Sender will be added, usually after the movement or copy of the drag and drop operation, or the tree has occurred after the tree has been added")] public evenet nodeaddhandler nodeadding;
[Description ("The node represented by Sender is removed, usually after the move drag and drop operation is completed, or the tree has occurred after the tree is loaded")]
Public Event Nodeeetehandler NodeDeleted;
[Description ("The node represented by Sender is added, usually after the movement or replication drag and drop operation is completed, or the tree has occurred after the tree is added")]
Public event nodeaddhandler nodeadded;
[Description ("This event occurs from the lowest layer when calling Browsenodes")]
Public Event Browsetreenodeseeventrandler InverseBrowSetreenodes;
[Description "]]]
Public Event Browsetreenodeseeventhandler DownBrowSetreenodes;
Public UptreeViewBase ()
{
InitializationComponent ();
}
///
/// Clean all the resources being used.
/// summary>
Protected Override Void Dispose (Bool Disposing)
{
IF (Disposing)
{
IF (Components! = NULL)
{
Components.dispose ();
}
}
Base.dispose (Disposing);
}
#REGION component designer generated code
///
/// Designer supports the required method - do not use the code editor to modify
/// This method is content.
/// summary>
Private vidinitiRizeComponent ()
{
Components = new system.componentmodel.container ();
}
#ndregion
#Region "Drag and drop"
///
/ / / Whether mobile type dragging
/// summary>
Public Bool CANMOVENODE
{
Get {return_movenode;
set
{
This.itemdrag - = new system.windows.forms.itemdrageventhandler (TreeView_ItemDrag);
THIS.DRAGENTER - = New system.windows.Forms.drageventHandler (TreeView_Dragenter);
THIS.DRAGDROP - = new system.windows.forms.drageventhandler (TreeView_DragDrop);
_MOVENODE = VALUE;
IF (_movenode)
{
This.itemdrag = new system.windows.forms.itemdrageventhandler (TreeView_ItemDrag);
THIS.DRAGENTER = New System.windows.Forms.drageventHandler (TreeView_Dragenter);
This.dragdrop = new system.windows.forms.drageventhandler (TreeView_DragDrop);
}
}
}
///
// / Whether copying drag and drop
/// summary>
Public Bool CancopyNode
{
Get {return _copyNode;
set
{
This.itemdrag - = new system.windows.forms.itemdrageventhandler (TreeView_ItemDrag);
THIS.DRAGENTER - = New system.windows.Forms.drageventHandler (TreeView_Dragenter);
THIS.DRAGDROP - = new system.windows.forms.drageventhandler (TreeView_DragDrop);
_CopyNode = Value;
IF (_copyNode)
{
This.itemdrag = new system.windows.forms.itemdrageventhandler (TreeView_ItemDrag);
THIS.DRAGENTER = New System.windows.Forms.drageventHandler (TreeView_Dragenter);
This.dragdrop = new system.windows.forms.drageventhandler (TreeView_DragDrop);
}
}
}
///
/// Start drag and drop
/// summary>
/// param>
/// param>
Protected void TreeView_itemdrag (Object Sender, System.Windows.Forms.ItemDrageventargs E)
{
THIS._DRAGNODE = (TREENODE) E.Item;
String strient = E.Item.toString ();
IF (_copyNode && _movenode)
DodragDrop (Stritem, Dragdropeffects.Move | DragDropeffects.copy);
Else IF (_copyNode)
DodragDrop (Stritem, DragDropeffects.copy);
Else IF (_Movenode)
DodragDrop (Stritem, DragDropeffects.move);
}
///
// / Down to the control border
/// summary>
/// param>
/// param>
Protected void TreeView_dragenter (Object Sender, System.Windows E)
{
IF (E.Data.GetdataPresent (DataFormats.Text))
{
IF ((E.KeyState & 4) == 4 && (E.Allowedeffect & DragDropeffects.move) == DragDropeffects.move) E.Effect = Dragdropeffects.Move; // Shift KeyState for move.
Else IF ((E.KeyState & 8) == 8 && (E.Allowedeffect & DragDropeffects.copy) == Dragdropeffects.copy
E.Effect = DragDropeffects.copy; // Ctrl KeyState for Copy.
Else IF (E.Allowedeffect & DragDropeffects.move) == Dragdropeffects.move)
E.Effect = Dragdropeffects.move; // by default, the drop action shouth be move, if allowed.
Else
E. Effect = Dragdropeffects.none;
}
Else
E. Effect = Dragdropeffects.none;
}
///
// / Drag and drop
/// summary>
/// param>
/// param>
Protected void treeview_dragdrop (object sender, system.windows.Forms.drageventargs e)
{
UPLIBRARY.UPControls.treenodeEventargs args = null;
Bool Cancel = False;
Point position = New Point (E.x, E.Y);
Position = this.PointToclient (position);
Treenode DropNode = this.getnode (position); // Carrying Node
IF (_dragnode.parent == DropNode) return; // Nothing
Treenode OldParent = _dragnode.parent;
IF ((E.Effect & DragDropeffects.move) == Dragdropeffects.move) // If it is a mobile type, just change the parent node
{
IF (ParentChangingBydraPDrop! = null)
{
Args = New Uplibrary.upControls.treenodeEventArgs (_Dragnode, OldParent, DropNode, TreenodeOperateType.Modify, Ref Cancel);
ParentChangingBydrapdrop (this, args);
IF (args.cancel == True) Return;
}
_Dragnode.remove ();
IF (DropNode! = NULL)
Dropnode.nodes .add (_dragnode); // If the tree node is at the root level, the Parent property is empty.
this.nodes.add (_dragnode);
IF (ParentChangeDBydraPDrop! = NULL)
{
Args = New Uplibrary.upControls.treenodeEventArgs (_Dragnode, OldParent, DropNode, TreenodeOperateType.Modify, Ref Cancel);
ParentChangeDBydrapdrop (this, args);
}
}
Else / / Otherwise, if you are replicated, you will add a new point at the bearing node.
{
Treenode TNode = (Treenode) _dragnode.clone (); // is a copy type of course to be new, copying parts include cloning tree nodes and below the tree structure
THIS.ADDNode (DropNode, TNode); // TNode and its son Node will join in the event
}
}
#ndregion
#Region "Add and remove Node and raise events"
///
/ / Add a new node to the specified superior Node
/// summary>
/// param>
/// param>
///
Public Bool AddNode (Treenode NewParent, String NodeText)
{
Return AddNode (NewParent, New Treenode (NodeText));
}
///
/ / Add a Node to the specified superior Node
/// summary>
/// param>
/// param>
///
Public Bool AddNode (Treenode Node)
{
Bool Cancel = False;
IF (Node! = NULL)
{
This.DownBrowSetreenodes = new browsenodeseventhandler (UptreeViewBase_BrowsetreenodesbyAdd);
TreenodeEventargs args = new TreenodeEventArgs (Node, Node.Parent, NewParent, TreenodeOperatetyPe.Addnew, Ref Cancel);
This.onadownBrowsetReenodes (args); // Let the first level in the event
THIS.DOWNBROWSETREENODES - = New BrowsetReenodeseventhandler (UptreeViewBase_BrowseTreenodesbyAdd);
}
Return! Cancel;
}
Private Void UptreeViewBase_BrowSetreenodesbyAdd (Object Sender, TreenodeEventArgs E) {
IF (E.OperateType == TreenodeOperateType.AddNew)
{
this.nodeadding! = NULL)
{
NodeAdding (this, e);
IF (e.cancel) return;
}
E.Node.Remove ();
IF (E.NEWParent! = NULL)
E.Newparent.nodes.add (e.node);
Else
THIS.NODES.ADD (E.NODE);
IF (this.nodeadded! = null)
NodeAdded (this, e);
}
}
///
/// Delete the current Node selected by the user
/// summary>
///
Public bool deletenode ()
{
Treenode node = this.selectedNode;
IF (Node! = NULL)
{
Return deletenode (node);
}
Return False;
}
///
/// Delete the Node and its sub-node specified by the parameter, starting from the lowest layer, and triggering event nodedeseting and nodedeted, respectively, after deleting node
/// summary>
/// param>
///
Public Bool DeleteNode (Treenode Node)
{
Bool Cancel = False;
IF (Node! = NULL)
{
This.inverseBrowSetreenodes = New Browsetreenodeseeventhandler (UptreeViewBase_BrowseTreenodesbyDelete);
TreenodeEventArgs args = new TreenodeEventArgs (Node, Node.Parent, Null, TreenodeOperateType.delete, Ref Cancel);
This.onInverseBrowsetReenodes (args); // let go to the first level to process in an event
THISINVERSEBROWSETREENODES - = New BrowseTreenodeseeventHandler (UptreeViewBase_BrowSetreenodesbyDelete);
}
Return! Cancel;
}
Private void UptreeViewBase_BrowSetreenodesbyDelete (Object Sender, TreenodeEventArgs E)
{
IF (E.OperateType == TreenodeOperateType.delete)
{
IF (this.nodeDeleding! = null)
{
NodeDeleding (this, e);
IF (e.cancel) return;
}
E.Node.Remove ();
IF (this.nodedeeted! = NULL)
NodeDeled (this, e);
}
}
#ndregion
#Region traverse and trigger an event
///
/// summary>
Protected Void OninVersebrowSetreenodes (TreenodeEventArgs Args)
{
Bool Cancel = False;
Treenode ChildNode = null, brothernode = null;
Treenode nodex = arggs.node;
IF (nodex == null) return;
IF (nodex.nodes.count> 0)
{
ChildNode = nodex.nodes [0]; // can be executed, indicating a sub-node
While (childnode! = null &&! args.cancel) // Brothers may have multiple
{
BrotherNode = childnode.nextnode;
TreenodeEventArgs arg = new treenodeEventArgs (childNode, childnode.parent, childnode.parent, args.operatetype, ref cancel);
OninVersebrowSetreenodes (arg);
Args.cancel = arg.cancel;
IF (arg.cancel) return;
ChildNode = BrotherNode;
}
}
If (! args.cancel) // If the cancel is specified in the next level, there is no incident of this level.
{
IF (InverseBrowSetreenodes! = NULL)
InverseBrowSetreenodes (this, args); // When there is no child node, the node is the end of the party, go to the event,
}
}
///
/ // The node and all the sub-nodes representing the parameter Nodex are not reversible in the event, and Cancel can only stop traversing.
/// summary>
Protected Void OnadownBrowsetReenodes (TreenodeEventArgs Args)
{
Bool Cancel = False;
Treenode ChildNode = null, brothernode = null;
Treenode nodex = arggs.node;
IF (Nodex! = NULL)
{
IF (DownBrowsetReenodes! = null)
DownBrowsetReenodes (this, args); // Treasure yourself
IF (args.cancel) return; // requires cancellation, no need for the next level
IF (nodex.nodes.count <= 0) return; // There is no next level.
ChildNode = nodex.nodes [0]; // can be executed, indicating a sub-node
While (childnode! = null &&! args.cancel) // Brothers may have multiple
{
BrotherNode = childnode.nextnode;
TreenodeEventargs arg = new treenodeEventArgs (childnode, childnode.parent, childnode.parent, args.operatetype, ref cancel); onadownBrowsetReenodes (arg);
Args.cancel = arg.cancel;
IF (arg.cancel) return;
ChildNode = BrotherNode;
}
}
}
#ndregion
}
///
/// Traverse the type of operation when the specified Node and its sub-node
/// summary>
Public Enum TreenodeOperateType
{
Browseonly = 1, AddNew, Modify, Delete
}
Public Class TreenodeEventArgs: System.EventArgs
{
Private treenode _node, _oldparent, _newparent;
PRIVATE BOOL_CANCEL;
Private TreenodeOperateType_operatetype;
///
/// When using this event data, Sender should be Node's Parent
/// summary>
/// To join the Node param> of Nodes represented by Sender
/// Active type of operation " param>
/// Whether the sewage param> is required in the event processing
Public TreenodeEventargs (Treenode Node, Treenode Oldparent, Treenode NewParent, TreenodeOperateType Operatety, Ref Bool Cancel): Base ()
{
_Oldparent = OldParent;
_Newparent = newparent;
_Node = node;
_CANCEL = Cancel;
_Operatetype = operatetype;
}
Public Treenode OldParent
{
Get {return _oldparent;
Set {_oldparent = value;
}
Public Treenode NewParent
{
Get {return _newparent;
Set {_newparent = value;}
}
Public TREENODE NODE
{
Get {return _node;}
Set {_node = value;}
}
Public TreenodeOperateType OperateType
{
Get {return _operatetype;
Set {_operatetype = value;
}
Public Bool Cancel
{
Get {
Return_Cancel;
}
SET {
_CANCEL = Value;
}
}
}
}