This commit is contained in:
633
PROMS/Volian.Controls.Library/vlnTreeView.cs
Normal file
633
PROMS/Volian.Controls.Library/vlnTreeView.cs
Normal file
@@ -0,0 +1,633 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices; // For DragHelper
|
||||
using System.Reflection;
|
||||
using VEPROMS.CSLA.Library;
|
||||
|
||||
namespace Volian.Controls.Library
|
||||
{
|
||||
public delegate void vlnTreeViewEvent(object sender, vlnTreeEventArgs args);
|
||||
public delegate bool vlnTreeViewBoolEvent(object sender, vlnTreeEventArgs args);
|
||||
public delegate TreeNode vlnTreeViewTreeNodeEvent(object sender, vlnTreeEventArgs args);
|
||||
//public delegate void vlnTreeViewDDEvent(object sender, System.Windows.Forms.DragEventArgs args);
|
||||
public partial class vlnTreeEventArgs
|
||||
{
|
||||
#region Business Methods
|
||||
private TreeNode _Node;
|
||||
public TreeNode Node
|
||||
{
|
||||
get { return _Node; }
|
||||
set { _Node = value; }
|
||||
}
|
||||
private TreeNode _Destination=null;
|
||||
public TreeNode Destination
|
||||
{
|
||||
get { return _Destination; }
|
||||
set { _Destination = value; }
|
||||
}
|
||||
private int _Index;
|
||||
public int Index
|
||||
{
|
||||
get { return _Index; }
|
||||
set { _Index = value; }
|
||||
}
|
||||
#endregion
|
||||
#region Factory Methods
|
||||
private vlnTreeEventArgs() { ;}
|
||||
public vlnTreeEventArgs(TreeNode node)
|
||||
{
|
||||
_Node = node;
|
||||
}
|
||||
public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index)
|
||||
{
|
||||
_Node = node;
|
||||
_Destination = destination;
|
||||
_Index = index;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public partial class vlnTreeView : TreeView
|
||||
{
|
||||
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
#region Events
|
||||
public event vlnTreeViewEvent NodeDragDrop;
|
||||
private void OnNodeDragDrop(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeDragDrop != null) NodeDragDrop(sender, args);
|
||||
}
|
||||
public event vlnTreeViewEvent NodeMove;
|
||||
private void OnNodeMove(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeMove != null) NodeMove(sender, args);
|
||||
}
|
||||
public event vlnTreeViewEvent NodeCopy;
|
||||
private void OnNodeCopy(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeCopy != null) NodeCopy(sender, args);
|
||||
}
|
||||
public event vlnTreeViewBoolEvent NodeDelete;
|
||||
private bool OnNodeDelete(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
bool result = true;
|
||||
if (NodeDelete != null) result = NodeDelete(sender, args);
|
||||
return result;
|
||||
}
|
||||
public event vlnTreeViewTreeNodeEvent NodeNew;
|
||||
private TreeNode OnNodeNew(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeNew != null) return NodeNew(sender, args);
|
||||
else return new TreeNode("New Item");
|
||||
}
|
||||
public event vlnTreeViewEvent NodeProperties;
|
||||
private void OnNodeProperties(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeProperties != null) NodeProperties(sender, args);
|
||||
}
|
||||
public event vlnTreeViewEvent NodeSelectionChange;
|
||||
private void OnNodeSelectionChange(object sender, vlnTreeEventArgs args)
|
||||
{
|
||||
if (NodeSelectionChange != null) NodeSelectionChange(sender, args);
|
||||
}
|
||||
#endregion
|
||||
#region Business Methods
|
||||
ImageList _dragImageList = new ImageList();
|
||||
#endregion
|
||||
#region Constructors
|
||||
public vlnTreeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.AllowDrop = true;
|
||||
DragHelper.InitCommonControls();
|
||||
this.ItemDrag += new ItemDragEventHandler(tv_ItemDrag);
|
||||
this.DragDrop += new DragEventHandler(tv_DragDrop);
|
||||
this.DragEnter += new DragEventHandler(tv_DragEnter);
|
||||
this.DragLeave += new EventHandler(tv_DragLeave);
|
||||
this.DragOver += new DragEventHandler(tv_DragOver);
|
||||
this.MouseDown += new MouseEventHandler(tv_MouseDown);
|
||||
base.AfterSelect += new TreeViewEventHandler(tv_AfterSelect);
|
||||
}
|
||||
private void tv_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
OnNodeSelectionChange(sender, new vlnTreeEventArgs(e.Node));
|
||||
}
|
||||
void tv_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
TreeNode tn = this.GetNodeAt(new Point(e.X, e.Y));
|
||||
if (tn != null)
|
||||
{
|
||||
this.SelectedNode = tn;
|
||||
Application.DoEvents();
|
||||
// Display Menu
|
||||
ToolStripMenuItem mi = new ToolStripMenuItem();
|
||||
ContextMenu cm = new ContextMenu();
|
||||
cm.MenuItems.Add("New...",new EventHandler(mi_Click));
|
||||
cm.MenuItems.Add("Cut", new EventHandler(mi_Click));
|
||||
cm.MenuItems.Add("Copy", new EventHandler(mi_Click));
|
||||
cm.MenuItems.Add("Paste", new EventHandler(mi_Click));
|
||||
cm.MenuItems.Add("Delete", new EventHandler(mi_Click));
|
||||
cm.MenuItems.Add("Properties...", new EventHandler(mi_Click));
|
||||
cm.Show(this, new Point(e.X, e.Y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mi_Click(object sender, EventArgs e)
|
||||
{
|
||||
MenuItem mi = (MenuItem)sender;
|
||||
switch (mi.Text)
|
||||
{
|
||||
case "New..."://Add a new child node at the current location
|
||||
// Should Give the option to the controling code to Add a New Node
|
||||
SelectedNode.Expand();
|
||||
TreeNode tn = OnNodeNew(this, new vlnTreeEventArgs(SelectedNode));
|
||||
if (tn != null)
|
||||
{
|
||||
SelectedNode.Nodes.Add(tn);
|
||||
if (LabelEdit)
|
||||
tn.BeginEdit();
|
||||
else
|
||||
SelectedNode = tn;
|
||||
}
|
||||
break;
|
||||
case "Cut"://Cut the selected node
|
||||
// Cut to Clipboard
|
||||
break;
|
||||
case "Copy"://Copy the selected node
|
||||
// Add to Clipboard
|
||||
break;
|
||||
case "Paste"://Paste the clipboard node
|
||||
// this is either a copy or a move depending upon where it came from
|
||||
// if it is from a cut then when the paste is done it should be set to a copy
|
||||
break;
|
||||
case "Delete"://Delete the selected node
|
||||
if(OnNodeDelete(this, new vlnTreeEventArgs(SelectedNode)))
|
||||
SelectedNode.Remove();
|
||||
break;
|
||||
case "Properties..."://Show the properties for the selected node
|
||||
OnNodeProperties(this,new vlnTreeEventArgs(SelectedNode));
|
||||
break;
|
||||
default:
|
||||
MessageBox.Show(string.Format("Unrecognized Menu Item '{0}'", mi.Text));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Cursor
|
||||
private bool SetupDragCursor(ImageList il, TreeNode tn)
|
||||
{
|
||||
// Reset image list used for drag image
|
||||
il.Images.Clear();
|
||||
int howBig = tn.Bounds.Size.Width + this.Indent;
|
||||
if (howBig > 256) howBig = 256;
|
||||
il.ImageSize = new Size(howBig, tn.Bounds.Height);
|
||||
|
||||
// Create new bitmap
|
||||
// This bitmap will contain the tree node image to be dragged
|
||||
Bitmap bmp = new Bitmap(tn.Bounds.Width + this.Indent, tn.Bounds.Height);
|
||||
|
||||
// Get graphics from bitmap
|
||||
Graphics gfx = Graphics.FromImage(bmp);
|
||||
|
||||
// Draw node icon into the bitmap
|
||||
if (this.ImageList != null) gfx.DrawImage(this.ImageList.Images[0], 0, 0);
|
||||
|
||||
// Draw node label into bitmap
|
||||
gfx.DrawString(tn.Text, this.Font, new SolidBrush(this.ForeColor),
|
||||
// new SolidBrush(Color.Blue),
|
||||
(float)this.Indent, 1.0f);
|
||||
|
||||
// Add bitmap to imagelist
|
||||
_dragImageList.Images.Add(bmp);
|
||||
|
||||
// Get mouse position in client coordinates
|
||||
Point p = this.PointToClient(Control.MousePosition);
|
||||
|
||||
// Compute delta between mouse position and node bounds
|
||||
int dx = p.X + this.Indent - tn.Bounds.Left;
|
||||
int dy = p.Y - tn.Bounds.Top;
|
||||
|
||||
// Begin dragging image
|
||||
return DragHelper.ImageList_BeginDrag(_dragImageList.Handle, 0, dx, dy);
|
||||
}
|
||||
private void tv_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
|
||||
{
|
||||
// Get drag node and select it
|
||||
try
|
||||
{
|
||||
TreeNode dragNode = (TreeNode)e.Item;
|
||||
Type t = dragNode.GetType();
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Item Drag {0} - {1}", t.FullName, t.BaseType.FullName);
|
||||
Type t2 = Type.GetType(t.FullName);
|
||||
if(t2 != null)
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Item Drag {0} - {1}", t2.FullName, t2.BaseType.FullName);
|
||||
this.SelectedNode = dragNode;
|
||||
if (SetupDragCursor(_dragImageList, dragNode))
|
||||
{
|
||||
this.DoDragDrop(dragNode, DragDropEffects.Move | DragDropEffects.Copy);// Begin dragging
|
||||
DragHelper.ImageList_EndDrag();// End dragging image
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_ItemDrag", ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public enum DropPosition : int
|
||||
{
|
||||
Child = 0, Before = 1, After = 2
|
||||
}
|
||||
private class DropLocation
|
||||
{
|
||||
#region Business Methods
|
||||
private TreeNode _dropNode;
|
||||
public TreeNode DropNode
|
||||
{
|
||||
get { return _dropNode; }
|
||||
set { _dropNode = value; }
|
||||
}
|
||||
private int _index;
|
||||
public int Index
|
||||
{
|
||||
get { return _index; }
|
||||
set { _index = value; }
|
||||
}
|
||||
private DropPosition _position;
|
||||
public DropPosition Position
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
DateTime _lastScroll;
|
||||
public DateTime LastScroll
|
||||
{
|
||||
get { return _lastScroll; }
|
||||
}
|
||||
private string _location = string.Empty;
|
||||
#endregion
|
||||
#region Constructors
|
||||
public DropLocation(TreeView tv, System.Windows.Forms.DragEventArgs e, DateTime lastScroll)
|
||||
{
|
||||
_lastScroll = lastScroll;
|
||||
_dropNode = tv.GetNodeAt(tv.PointToClient(new Point(e.X, e.Y)));
|
||||
if (_dropNode == null) return;
|
||||
int OffsetY = tv.PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top;
|
||||
if (OffsetY < _dropNode.Bounds.Height / 3) // First Third - Before
|
||||
{
|
||||
_index = _dropNode.Index;
|
||||
_dropNode = _dropNode.Parent;
|
||||
_position = DropPosition.Before;
|
||||
_location = string.Format("Before1 {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
|
||||
}
|
||||
else if ((OffsetY / 2) < _dropNode.Bounds.Height / 3) // Second Third - Child
|
||||
{
|
||||
_location = string.Format("Child {0} y={1}", _dropNode.Text, OffsetY);
|
||||
_position = DropPosition.Child;
|
||||
_index = 0;
|
||||
if (_dropNode.Parent == null)
|
||||
{
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.Info("Root Node");
|
||||
}
|
||||
}
|
||||
else // Last Third - After Now I need to check the X value
|
||||
{
|
||||
if (_dropNode.NextVisibleNode !=null && _dropNode.Nodes.Count > 0)// Has Children - Insert first child
|
||||
{
|
||||
// _dropNode = _dropNode.Nodes[0];
|
||||
_index = 0;
|
||||
_position = DropPosition.Before;
|
||||
_location = string.Format("Before2 {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
|
||||
}
|
||||
else // No Children - Insert Next at various levels
|
||||
{
|
||||
Point pt = tv.PointToClient(new Point(e.X, e.Y));
|
||||
TreeNode nextParent = _dropNode.NextNode;
|
||||
if (nextParent != null) nextParent = nextParent.Parent;
|
||||
do
|
||||
{
|
||||
_index = _dropNode.Index;
|
||||
_dropNode = _dropNode.Parent;
|
||||
} while (pt.X < _dropNode.Bounds.X && _dropNode != nextParent);
|
||||
_location = string.Format("After {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
|
||||
_position = DropPosition.After;
|
||||
}
|
||||
}
|
||||
LimitMoves(e);
|
||||
}
|
||||
public void LimitMoves(DragEventArgs e)
|
||||
{
|
||||
if ((e.KeyState & 8) == 0)
|
||||
{
|
||||
//TreeNode dragNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
|
||||
//TreeNode dragNode = (TreeNode)e.Data.GetData("TreeTest.FolderTreeNode");
|
||||
TreeNode dragNode = vlnTreeView.GetTreeNodeFromData(e.Data);
|
||||
switch (_position)
|
||||
{
|
||||
case DropPosition.Before:
|
||||
if (dragNode == _dropNode.Nodes[_index] || dragNode == _dropNode.Nodes[_index].PrevNode)
|
||||
{
|
||||
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Before {0} {1} {2} {3} {4}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
|
||||
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode);
|
||||
_dropNode = null;
|
||||
}
|
||||
break;
|
||||
case DropPosition.Child:
|
||||
if (dragNode.Parent == _dropNode)
|
||||
{
|
||||
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Child {0} {1} {2} {3} {4} {5}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
|
||||
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode,DateTime.Now);
|
||||
_dropNode = null;
|
||||
}
|
||||
break;
|
||||
case DropPosition.After:
|
||||
if (dragNode == _dropNode.Nodes[_index] || dragNode == _dropNode.Nodes[_index].NextNode)
|
||||
{
|
||||
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("After {0} {1} {2} {3} {4}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
|
||||
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode);
|
||||
_dropNode = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}[{1}].{2}", _dropNode.Text, _index, _position.ToString());
|
||||
}
|
||||
#region Drawing
|
||||
private void TreeNodeTriangle(Graphics g)
|
||||
{
|
||||
Rectangle r = _dropNode.Bounds;
|
||||
int RightPos = r.Right + 6;
|
||||
Point[] RightTriangle = new Point[]{
|
||||
new Point(RightPos, r.Y ),
|
||||
new Point(RightPos - (r.Height / 2), r.Y + (r.Height / 2)),
|
||||
new Point(RightPos, r.Y + r.Height),
|
||||
new Point(RightPos - (r.Height / 3), r.Y + (r.Height / 2))
|
||||
};
|
||||
g.FillPolygon(System.Drawing.Brushes.Black, RightTriangle);
|
||||
}
|
||||
private void InsertPointer(TreeNode tn, Graphics g)
|
||||
{
|
||||
TreeView tv = _dropNode.TreeView;
|
||||
Rectangle r2 = _dropNode.Nodes[_index].Bounds;
|
||||
Rectangle r3 = tn.Bounds;
|
||||
int y = (_position == DropPosition.Before ? r2.Y : r3.Bottom);
|
||||
int x = r2.Left;
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Line at {0} Node {1}[{2}] {3}", _location, _dropNode.Text, _index, _position.ToString());
|
||||
Color lc = (_position == DropPosition.After ? Color.Red : Color.Blue);
|
||||
Brush lb = (_position == DropPosition.After ? Brushes.Red : Brushes.Blue);
|
||||
Point[] RightTriangle;
|
||||
if (_position == DropPosition.After)
|
||||
{
|
||||
RightTriangle = new Point[]{
|
||||
new Point(x, y ),
|
||||
new Point(x+4, y+4),
|
||||
new Point(x+8, y)};
|
||||
}
|
||||
else
|
||||
{
|
||||
RightTriangle = new Point[]{
|
||||
new Point(x, y),
|
||||
new Point(x+4, y-4),
|
||||
new Point(x+8, y)};
|
||||
}
|
||||
g.DrawLine(new System.Drawing.Pen(lc, 2), new Point(r2.Left, y), new Point(tv.Width - 8, y));
|
||||
g.FillPolygon(lb, RightTriangle);
|
||||
}
|
||||
public void ShowLocation(System.Windows.Forms.DragEventArgs e, bool ScrollOnly)
|
||||
{
|
||||
//if (e.Effect == DragDropEffects.None) return;
|
||||
if (_dropNode != null)
|
||||
{
|
||||
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("ShowLocation1 {0} {1}", e.Effect.ToString(), DateTime.Now.Millisecond);
|
||||
DragHelper.ImageList_DragShowNolock(false);
|
||||
TreeView tv = _dropNode.TreeView;
|
||||
TreeNode tmp = tv.GetNodeAt(tv.PointToClient(new Point(e.X, e.Y)));
|
||||
// if (!ScrollOnly)
|
||||
// {
|
||||
if (ScrollTreeView(tmp) || !ScrollOnly)
|
||||
{
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("ShowLocation2 {0} {1}", e.Effect.ToString(), DateTime.Now.Millisecond);
|
||||
tv.Refresh();
|
||||
if (e.Effect != DragDropEffects.None)
|
||||
{
|
||||
//tv.SelectedNode = dropNode;
|
||||
Graphics g = tv.CreateGraphics();
|
||||
TreeNodeTriangle(g);
|
||||
if (_position != DropPosition.Child)InsertPointer(tmp, g);
|
||||
}
|
||||
}
|
||||
// }
|
||||
// else ScrollTreeView(tmp);
|
||||
DragHelper.ImageList_DragShowNolock(true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public void ShowLocation()
|
||||
{
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("{0}[{1}] {2}", _dropNode.Text, _index, _position.ToString());
|
||||
}
|
||||
#region AutoScroll
|
||||
private bool ScrollTreeView(TreeNode tn)
|
||||
{
|
||||
bool retval = false;
|
||||
TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - _lastScroll.Ticks);
|
||||
if (ts.Milliseconds > 100)// This controls the scroll speed
|
||||
{
|
||||
int top = tn.Bounds.Top;
|
||||
_lastScroll = DateTime.Now;
|
||||
if (tn.TreeView.ClientSize.Height < tn.Bounds.Bottom) tn.EnsureVisible();// Make sure that the current node is visible
|
||||
if (tn.NextVisibleNode != null && tn.TreeView.ClientSize.Height < tn.NextVisibleNode.Bounds.Bottom)
|
||||
tn.NextVisibleNode.EnsureVisible();// Make sure that the next node is visible
|
||||
else
|
||||
if (tn.PrevVisibleNode != null && tn.PrevVisibleNode.PrevVisibleNode != null && tn.PrevVisibleNode.PrevVisibleNode.IsVisible == false)
|
||||
tn.PrevVisibleNode.PrevVisibleNode.EnsureVisible();// Make sure that the previous node is visible }
|
||||
else
|
||||
if (tn.PrevVisibleNode != null && tn.PrevVisibleNode.IsVisible == false)
|
||||
tn.PrevVisibleNode.EnsureVisible();// Make sure that the previous node is visible
|
||||
retval = (top != tn.Bounds.Top);
|
||||
// if (retval) if(_MyLog.IsInfoEnabled)_MyLog.Info("Scroll");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endregion
|
||||
public bool Equals(DropLocation dl)
|
||||
{
|
||||
return (dl != null && _lastScroll.Equals(dl.LastScroll) && _dropNode.Equals(dl.DropNode) &&
|
||||
_position.Equals(dl.Position));
|
||||
}
|
||||
}
|
||||
private DropLocation _LastDropLocation = null;
|
||||
private void tv_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
TreeNode dragNode = GetTreeNodeFromData(e.Data);
|
||||
// Compute drag position and move image
|
||||
Point formP = this.FindForm().PointToClient(new Point(e.X, e.Y));
|
||||
DragHelper.ImageList_DragMove(formP.X - this.Left, formP.Y - this.Top);
|
||||
DropLocation dl = new DropLocation(this, e, _LastDropLocation == null ? DateTime.Now : _LastDropLocation.LastScroll);
|
||||
string s = string.Empty;
|
||||
if (dl.DropNode == null)
|
||||
{
|
||||
e.Effect = DragDropEffects.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
DragDropEffects ee = e.Effect;
|
||||
if ((e.KeyState & 8) == 8)
|
||||
ee = DragDropEffects.Copy; // Copy it
|
||||
else
|
||||
ee = DragDropEffects.Move; // Move it
|
||||
if (IsChild(dragNode, dl.DropNode))
|
||||
ee = DragDropEffects.None; // Don't copy or move to a child node
|
||||
if (e.Effect != ee) e.Effect = ee;
|
||||
dl.ShowLocation(e, dl.Equals(_LastDropLocation));
|
||||
_LastDropLocation = dl;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_DragOver", ex);
|
||||
}
|
||||
}
|
||||
private static TreeNode GetTreeNodeFromData(IDataObject datobj)
|
||||
{
|
||||
foreach (string s in datobj.GetFormats())
|
||||
{
|
||||
try
|
||||
{
|
||||
return (TreeNode)datobj.GetData(s);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(_MyLog.IsErrorEnabled)_MyLog.Error("GetTreeNodeFromData", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private void tv_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
TreeNode dragNode = GetTreeNodeFromData(e.Data);
|
||||
DragHelper.ImageList_DragLeave(this.Handle);
|
||||
int index = _LastDropLocation.Index + (_LastDropLocation.Position == DropPosition.After ? 1 : 0);
|
||||
if (dragNode.Parent == _LastDropLocation.DropNode && dragNode.Index <= _LastDropLocation.Index) index--;
|
||||
if (e.Effect == DragDropEffects.Move)// If Move Remove drag node from parent
|
||||
dragNode.Remove();
|
||||
else
|
||||
dragNode = Clone(dragNode);
|
||||
_LastDropLocation.DropNode.Nodes.Insert(index, dragNode);
|
||||
this.SelectedNode = dragNode;
|
||||
OnNodeDragDrop(sender, new vlnTreeEventArgs(dragNode, _LastDropLocation.DropNode,index));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_DragDrop", ex);
|
||||
}
|
||||
}
|
||||
private void DumpMembers(object o)
|
||||
{
|
||||
Type t = o.GetType();
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("\r\n\r\nMembers for type {0}", t.ToString());
|
||||
MemberInfo[] mis = t.GetMembers();
|
||||
int i = 0;
|
||||
foreach (MemberInfo mi in mis)
|
||||
{
|
||||
i++;
|
||||
try
|
||||
{
|
||||
if(mi.MemberType != MemberTypes.Method)
|
||||
if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("{0} {1} {2}", i, mi.Name, mi.MemberType);
|
||||
// if (fi.Name == "TreeView")
|
||||
// fi.SetValue(o, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(_MyLog.IsErrorEnabled)_MyLog.Error("DumpMembers", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
private TreeNode Clone(TreeNode tn)
|
||||
{
|
||||
|
||||
TreeNode tmp = (TreeNode)tn.Clone();
|
||||
ExpandMatch(tmp,tn);
|
||||
return tmp;
|
||||
}
|
||||
private void tv_DragDropOld(object sender, System.Windows.Forms.DragEventArgs e)
|
||||
{
|
||||
TreeNode dragNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");// Get the drag node
|
||||
DragHelper.ImageList_DragLeave(this.Handle);
|
||||
TreeNode cloneNode = (TreeNode)dragNode.Clone();// copy the source node
|
||||
ExpandMatch(cloneNode, dragNode);
|
||||
_LastDropLocation.DropNode.Nodes.Insert(_LastDropLocation.Index + (_LastDropLocation.Position == DropPosition.After ? 1 : 0), cloneNode);
|
||||
if (e.Effect == DragDropEffects.Move)// If Move Remove drag node from parent
|
||||
dragNode.Remove();
|
||||
this.SelectedNode = cloneNode;
|
||||
}
|
||||
private void tv_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
|
||||
{
|
||||
DragHelper.ImageList_DragEnter(this.Handle, e.X - this.Left, e.Y - this.Top);
|
||||
}
|
||||
private void tv_DragLeave(object sender, System.EventArgs e)
|
||||
{
|
||||
DragHelper.ImageList_DragLeave(this.Handle);
|
||||
this.Refresh();
|
||||
}
|
||||
private void ExpandMatch(TreeNode tn1, TreeNode tn2)
|
||||
{
|
||||
if (tn2.IsExpanded) tn1.Expand();
|
||||
foreach (TreeNode tc in tn2.Nodes) ExpandMatch(tn1.Nodes[tc.Index], tc);
|
||||
}
|
||||
private bool IsChild(TreeNode parent, TreeNode child)
|
||||
{
|
||||
if (parent.Equals(child)) return true;// Check against self
|
||||
foreach (TreeNode tc in parent.Nodes) if (IsChild(tc, child)) return true;//Check all children
|
||||
return false;// Must not be a child at this level
|
||||
}
|
||||
}
|
||||
public class DragHelper
|
||||
{
|
||||
[DllImport("comctl32.dll")]
|
||||
public static extern bool InitCommonControls();
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool ImageList_BeginDrag(IntPtr himlTrack, int
|
||||
iTrack, int dxHotspot, int dyHotspot);
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool ImageList_DragMove(int x, int y);
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern void ImageList_EndDrag();
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool ImageList_DragLeave(IntPtr hwndLock);
|
||||
|
||||
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool ImageList_DragShowNolock(bool fShow);
|
||||
static DragHelper()
|
||||
{
|
||||
InitCommonControls();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user