 |
|
 |
This code is very usefull for me. but still hve some issues.I have 2 treeviews, and i have to restrict some nodes being dragged. when i try to drag and drop this restriced node to the same treeview its working fine(drag cancelled). But when i drop this restricted node to another treeview its getting copied and removing from first treeview. an anyone help me to restrict this node being dragged to any treeview.
anu&jiby
|
| Sign In·View Thread·PermaLink | 3.00/5 |
|
|
|
 |
|
 |
As others have mentioned it is kind of buggy, the fact that it made my tree view smaller while I was dragging kinda turned me off. It also flickers alot.
AliR. Visual C++ MVP
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It was mentioned earlier, great article topic, because treeviews are such popular controls, but its flicker full and the auto resize doesnt work if you are dragging a node to the bottom, could have been a killer if some usability issues were covered.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
Hello, I am wondering if anyone would know how to drag and drop from one tree control to another tree control? Thanks
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
 |
if the answere is yes, where can i download it?
if no, it give me this error:
Visual Studio cannot start debugging because the debug target 'C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe' is missing. Please build the project and retry, or set the OutputPath and AssemblyName properties appropriately to point at the correct location for the target assembly. Visual Studio cannot start debugging because the debug target 'C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe' is missing. Please build the project and retry, or set the OutputPath and AssemblyName properties appropriately to point at the correct location for the target assembly.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
You probably need to change the startup project. Right click on the "TestApp" project and select "Set as Startup Project"
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I had quite a few problems with this code (some of which have already been reported) including:
-Treeview control itself resizing when dragging. -Source node being deleted with copy operations. -High flicker rate due to redrawing on small cursor movements. -Events not firing (due to events in base class not being called). -Target node still showing as selected after aborting a drag operation. -Should be easier to control what type of nodes you can drag ONTO, not only which ones you can initiate dragging FROM. -Cntrl/Shift/Alt + Drag not implemented
That said, I did still find it to be useful starting point.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi I am trying to add nodes into the treeview by dragging items to the treeview. Could you please tell me how to do that? Thanks!
Sebi
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hi,
I ran the test application and there is a problem with node highlighting: background color turn black and remain black. Maybe the code doesn't work anymore and needs to be updated?
Mathieu
|
| Sign In·View Thread·PermaLink | 1.50/5 |
|
|
|
 |
|
|
 |
|
 |
It's because in the code the node is set to background color of "HighlightText" which on most systems is default. I believe this is a mistake and should be set to SystemColors.Window. At least that's what worked for me.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This is great, but what if you can drag the node, but need to cancel the drag according to the node you are trying to drop it on? Like a document, shouldnt become a child of another document. But when I try to do a DragDrop event to cancel it, it never gets called. Is there a fix I need to do to this control, or would you be able to post a fixed update that would allow this?
Thanks!!!!
invid http://invid.funxion.net
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
hi, how can I drag data from other control to this treeview, It will not fire the dragcomplete event.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
I have a number of nodes that I need to update as part of a process i.e. change the icon as each node task is completed. However when I use the node.EnsureVisible() method, if the node text is long and the scroll bars are visible it scrolls way over to the right, hiding the navigation lines/crosses - quite annoying.
I created a method "EnsureVisibleWithoutRightScrolling" that can be called instead of EnsureVisible() and added the following code to fix this:
// Sendmessage constants private const int WM_HSCROLL = 276; private const int SB_LEFT = 6;
[DllImport("user32.dll")] private static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
public void EnsureVisibleWithoutRightScrolling(TreeNode node) { this.BeginUpdate();
// we do the standard call.. node.EnsureVisible(); // ..and afterwards we scroll to the left again! SendMessage(this.Handle, WM_HSCROLL, SB_LEFT , 0);
this.EndUpdate(); }
Original article for EnsureVisibleWithoutRightScrolling is here:
http://www.codeproject.com/cs/miscctrl/NoScrollingTree.asp[^]
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
you can use the API function CreateIconIndirect to create any cursor from a bitmap. There is not size limit so you can draw the item into a bitmap and convert it into a cursor. The following class can be used for that. An instance of this class must exists as long as the cursor is displayed.
using System; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices;
namespace aux { public class BitmapCursor : IDisposable { #region Win-API imports
[StructLayout(LayoutKind.Sequential)] public struct ICONINFO { public bool fIcon; public uint xHotspot; public uint yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; }
[System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern IntPtr CreateIconIndirect( ref ICONINFO iconinfo ); [System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern bool DestroyIcon( IntPtr hIcon );
#endregion
#region private
private ICONINFO iconInfo; private Cursor cursor = null; private IntPtr handle = IntPtr.Zero; private void Create() { handle = CreateIconIndirect( ref iconInfo ); cursor = new Cursor( handle ); }
#endregion #region constructors and destructor
public BitmapCursor( System.Drawing.Bitmap bmp, int HotSpotX, int HotSpotY ) { iconInfo = new ICONINFO(); iconInfo.fIcon = false; iconInfo.xHotspot = 0; iconInfo.yHotspot = 0; iconInfo.hbmMask = bmp.GetHbitmap(); iconInfo.hbmColor = bmp.GetHbitmap(); Create(); } public BitmapCursor( System.Drawing.Bitmap bmp, Cursor Cursor ) { iconInfo = new ICONINFO(); iconInfo.fIcon = false; iconInfo.xHotspot = 0; iconInfo.yHotspot = 0; using( System.Drawing.Bitmap bmpdup = bmp.Clone() as System.Drawing.Bitmap ) { using( Graphics g = Graphics.FromImage( bmpdup ) ) { Cursor.Draw( g, new Rectangle( new Point( 0, 0 ), Cursor.Size ) ); } iconInfo.hbmMask = bmpdup.GetHbitmap(); iconInfo.hbmColor = bmpdup.GetHbitmap(); Create(); } }
~BitmapCursor() { Dispose( false ); } #endregion
#region virtual methods
protected virtual void Dispose( bool disposing ) { try { if( handle != IntPtr.Zero ) DestroyIcon( handle ); } catch { } }
#endregion
#region public properties
public Cursor Cursor { get { return cursor; } }
#endregion
#region IDisposable Member
public void Dispose() { GC.SuppressFinalize( this ); Dispose( true ); }
#endregion } }
Example for creating a drag cursor from a TreeNode that look like Windows-Explorer:
private BitmapCursor dragBitmapCursor = null;
protected virtual Cursor CreateDragCursor( TreeNode node ) { int width = node.Bounds.Width; int height = node.Bounds.Height; Rectangle r = new Rectangle( 0, 0, width, height ); using( Graphics g0 = CreateGraphics() ) using( Bitmap bmp = new Bitmap( width, height * 4, g0 ) ) using( Graphics g = Graphics.FromImage( bmp ) ) { g.Clear( Color.FromArgb( 0, 0, 0, 0 ) );
Color cb1 = Color.FromArgb( 255, 0, 89, 181 ); Color cb2 = Color.FromArgb( 0, 0, 89, 181 ); using( Brush b = new System.Drawing.Drawing2D.LinearGradientBrush( r, cb1, cb2, 0, false ) ) g.FillRectangle( b, 0, 0, width, height );
Color ct1 = Color.FromArgb( 255, 255, 255, 255 ); Color ct2 = Color.FromArgb( 64, 255, 255, 255 ); using( Brush b = new System.Drawing.Drawing2D.LinearGradientBrush( r, ct1, ct2, 0, false ) ) g.DrawString( node.Text, Font, b, 0, 0 );
DragBitmapCursor = new BitmapCursor( bmp, Cursors.Default ); return DragBitmapCursor.Cursor; } }
|
| Sign In·View Thread·PermaLink | 4.78/5 |
|
|
|
 |
|
 |
CreateDragCursor: creates Cursor with expanded Subnodes...
Public Class BitmapCursor Implements IDisposable
#Region "variables"
Private icon_Info As ICONINFO Private cursor_ As System.Windows.Forms.Cursor = Nothing Private handle As IntPtr = IntPtr.Zero
#End Region
#Region "constants"
Private Shared ReadOnly TreeviewOffset As System.Drawing.Point = New System.Drawing.Point(-1, 2) Private Const Alpha As Double = 0.33
#End Region
_ Private Structure ICONINFO
Public fIcon As Boolean Public xHotspot As System.UInt32 Public yHotspot As System.UInt32 Public hbmMask As IntPtr Public hbmColor As IntPtr
End Structure
_ Private Shared Function CreateIconIndirect(ByRef iconinfo As ICONINFO) As IntPtr End Function
_ private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean End Function
Private Sub Create()
handle = CreateIconIndirect(icon_Info) cursor_ = New Cursor(handle)
End Sub
Private Sub New(ByVal bmp As System.Drawing.Bitmap, ByVal HotSpotX As Integer, ByVal HotSpotY As Integer) icon_Info = New ICONINFO() icon_Info.fIcon = False icon_Info.xHotspot = 0 icon_Info.yHotspot = 0 icon_Info.hbmMask = bmp.GetHbitmap() icon_Info.hbmColor = bmp.GetHbitmap() Create()
End Sub
' ' Creates a cursor from a bitmap and combines it with another cursor. ' Private Sub New(ByVal bmp As System.Drawing.Bitmap, ByVal CursorToCombine As System.Windows.Forms.Cursor)
icon_Info = New ICONINFO() icon_Info.fIcon = False icon_Info.xHotspot = 0 icon_Info.yHotspot = 0 Using bmpdup As System.Drawing.Bitmap = CType(bmp.Clone(), System.Drawing.Bitmap) Using g As Graphics = System.Drawing.Graphics.FromImage(bmpdup) CursorToCombine.Draw(g, New System.Drawing.Rectangle(New Point(0, 0), CursorToCombine.Size)) End Using icon_Info.hbmMask = bmpdup.GetHbitmap() icon_Info.hbmColor = bmpdup.GetHbitmap() Create() End Using
End Sub
Private ReadOnly Property Cursor() As System.Windows.Forms.Cursor Get Return Me.cursor_ End Get End Property
Public Shared Function CreateDragCursor(ByRef NodeToDraw As System.Windows.Forms.TreeNode, ByRef CursorToCombine As System.Windows.Forms.Cursor) As Cursor
If Not NodeToDraw Is Nothing Then Dim NodesBounds As System.Drawing.Rectangle = GetNodesBounds(NodeToDraw)
Dim ControlScreenshot As System.Drawing.Bitmap = New System.Drawing.Bitmap(NodeToDraw.TreeView.Width, NodeToDraw.TreeView.Height) Dim CursorBitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(Math.Max(NodesBounds.Width, CursorToCombine.Size.Width), Math.Max(NodesBounds.Height, CursorToCombine.Size.Height)) Dim CursorBitmapRectangle As System.Drawing.Rectangle = New System.Drawing.Rectangle(0, 0, NodesBounds.Width, NodesBounds.Height)
NodeToDraw.TreeView.DrawToBitmap(ControlScreenshot, New System.Drawing.Rectangle(0, 0, ControlScreenshot.Width, ControlScreenshot.Height))
Using g As Graphics = Graphics.FromImage(CursorBitmap) g.Clear(NodeToDraw.TreeView.BackColor) g.DrawImage(ControlScreenshot, CursorBitmapRectangle, NodesBounds, GraphicsUnit.Pixel) End Using
Call AdjustAlpha(CursorBitmap, Alpha, NodeToDraw.TreeView.BackColor)
Return New BitmapCursor(CursorBitmap, CursorToCombine).Cursor Else Return CursorToCombine End If
End Function
Private Shared Function GetNodeBounds(ByRef NodeToDraw As System.Windows.Forms.TreeNode) As System.Drawing.Rectangle
If Not NodeToDraw Is Nothing Then Try Return New Rectangle(NodeToDraw.Bounds.Left - NodeToDraw.TreeView.ImageList.ImageSize.Width + TreeviewOffset.X, NodeToDraw.Bounds.Top + TreeviewOffset.Y, NodeToDraw.Bounds.Width + NodeToDraw.TreeView.ImageList.ImageSize.Width, NodeToDraw.Bounds.Height) Catch ex As Exception Return New Rectangle(NodeToDraw.Bounds.Left - 1, NodeToDraw.Bounds.Top + 2, NodeToDraw.Bounds.Width, NodeToDraw.Bounds.Height) End Try Else Return System.Drawing.Rectangle.Empty End If
End Function
Private Shared Function GetNodesBounds(ByRef NodeToDraw As System.Windows.Forms.TreeNode) As System.Drawing.Rectangle
Dim ChildNode As System.Windows.Forms.TreeNode Dim Result As System.Drawing.Rectangle If Not NodeToDraw Is Nothing Then Result = GetNodeBounds(NodeToDraw) If NodeToDraw.IsExpanded AndAlso NodeToDraw.Nodes.Count > 0 Then If NodeToDraw.Nodes.Count > 0 Then For Each ChildNode In NodeToDraw.Nodes Result = System.Drawing.Rectangle.Union(Result, GetNodesBounds(ChildNode)) Next ChildNode End If End If Return Result Else Return System.Drawing.Rectangle.Empty End If
End Function ^ private Sub AdjustAlpha(ByRef ImageToAdjust As System.Drawing.Bitmap, ByVal Alpha As Double, ByRef TransparencyColor As System.Drawing.Color)
Dim ActColor As System.Drawing.Color Dim x, y As Integer Dim AlphaByte As Integer = CInt(Math.Round(Alpha * 255)) For x = 0 To ImageToAdjust.Width - 1 Step 1 For y = 0 To ImageToAdjust.Height - 1 Step 1 ActColor = ImageToAdjust.GetPixel(x, y) If ActColor.R = TransparencyColor.R AndAlso _ ActColor.G = TransparencyColor.G AndAlso _ ActColor.B = TransparencyColor.B Then ImageToAdjust.SetPixel(x, y, Color.FromArgb(0, ActColor)) Else ImageToAdjust.SetPixel(x, y, Color.FromArgb(AlphaByte, ActColor)) End If Next y Next x
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
End Sub
Private Sub Dispose() Implements IDisposable.Dispose
GC.SuppressFinalize(Me) Dispose(True)
End Sub
Private Sub Dispose(ByVal disposing As Boolean)
Try If Not handle = IntPtr.Zero Then DestroyIcon(handle) End If Catch ex As Exception
End Try
End Sub
End Class
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
In my app I wanted to make the icon jump a certain amount of pixels instead of following the mouse pointer px per px.
So i have implemented an onMouseMove event which has to change the hotspot of the cursor continiously. Therefore everytime a new cursor has to be created.
After a few hundred times you'll get an numericargumentexception from the win32 api.
solution: you have to destroy the current handle with "DestroyIcon" before creating a new one.
also constructor with hotspot was not setting the hotspot
Here the new class with my updates and changes to my needs.
This was a great help for me, as suprisinly, there's not alot to find on the topic.
using System; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices;
namespace PerdumImageEditor._Klassen { public class clsBitmapCursor : IDisposable { #region Win-API imports
[StructLayout(LayoutKind.Sequential)] public struct ICONINFO { public bool fIcon; public uint xHotspot; public uint yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; }
[System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern IntPtr CreateIconIndirect( ref ICONINFO iconinfo ); [System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern bool DestroyIcon( IntPtr hIcon );
#endregion
private ICONINFO iconInfo; private Cursor cursor = null; private IntPtr handle = IntPtr.Zero;
#region constructors and destructor public clsBitmapCursor(System.Drawing.Bitmap bmp) { iconInfo = new ICONINFO(); iconInfo.fIcon = false; iconInfo.xHotspot = 0; iconInfo.yHotspot = 0; iconInfo.hbmMask = bmp.GetHbitmap(); iconInfo.hbmColor = bmp.GetHbitmap(); Create(); } public clsBitmapCursor( System.Drawing.Bitmap bmp, uint HotSpotX, uint HotSpotY ) { iconInfo = new ICONINFO(); iconInfo.fIcon = false; iconInfo.xHotspot = HotSpotX; iconInfo.yHotspot = HotSpotY; iconInfo.hbmMask = bmp.GetHbitmap(); iconInfo.hbmColor = bmp.GetHbitmap(); Create(); }
~clsBitmapCursor() { Dispose( false ); }
#endregion
protected virtual void Dispose( bool disposing ) { try { if( handle != IntPtr.Zero ) DestroyIcon( handle ); } catch { } }
public void moveHotspot(int x, int y) { iconInfo.xHotspot = (uint)x; iconInfo.yHotspot = (uint)y;
Create(); }
private void Create() { if (handle != null) DestroyIcon(handle);
handle = CreateIconIndirect(ref iconInfo); cursor = new Cursor(handle); }
public Cursor Cursor { get { return cursor; } }
public void Dispose() { GC.SuppressFinalize( this ); Dispose( true ); }
} }
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
I have two types of nodes in my treeview, regular nodes and 'myTreeNodes' which just contain some extra information (such as an Image object). I noticed that if i move one regular node into another regular node, all the 'myTreeNodes' in the node i just moved get messed up, losing all the values for their custom fields.
i traced this to the Clone method you suggested using when copying the nodes.
This is the fix i propose, it works well:
In the DragDrop method:
dragNode.Remove(); targetNode.Nodes.Insert(0, dragNode); targetNode.Expand();
you don't need to clone it, because removing it only takes it out of its parent nodelist, as long as you maintain a reference to the object, you maintain all the data in the object. I used Insert because i was short on time and i used Insert for node-swapping in my treeview, add should work just as well.
by the way, thanks for your code, it was very helpful
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Thanx for this control. It saves me a lot of time. The OnDragLeave event does not set the previous node to the 'not selected' color. This means that whenever you leave the control while dragging something the previous node stays 'selected'. Your whole tree can appear selected after a while.
I made this code change:
if ( this._previousNode != null ) { this._previousNode.BackColor = SystemColors.HighlightText; this._previousNode.ForeColor = SystemColors.ControlText; }
Cheers
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
actually the problem is that the node is never ACTUALLY selected.
instead of tracking the previous and next node, and then setting the colors, why don't you just do
this.selectedNode = targetNode (or something to that extent.. i don't have the code up right now)
but anyway, yes... treeviews have a property for the selected node, just set that property to the node that is at the current point.
[note: i'm on .net 2.0 beta 2 right now, so you may not have that]
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi smallguy78! when I wrote my node named MyNode extend TreeNode, ur control didnt work???
Can u show me how to correct it?
Thanks
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
(Not being the author) but my guess would be "absolutely, yes". You would need to convert this all from C# to VB.NET of course - or you could take the simpler option and create this project as C#, and then include a reference to the project in your VB.NET application. Probably save you some conversion time, but up to you of course
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |