|

Introduction
One of the common behaviors developers want to implement with treeviews is drag and drop. For some reason, Microsoft haven't made this entirely easy with the .NET TreeView control (and it hasn't changed in the 2.0 beta either). Whilst it's not really that challenging to do, it makes sense to have a single control that has the behavior built in, instead of cutting and pasting the event each time you want to implement drag and drop in a treeview.
Drag and drop is based around 4 events: OnDragDrop, OnDragEnter, OnDragLeave, OnDragOver, and in the TreeView control, OnItemDrag. I won't bother going over the order in which these events are called or what they do, you can read the MSDN docs for that, or use Google. Suffice to say, these events have all been implemented in this TreeViewDragDrop control.
Features of the control
I built the control for a management application for a website I store code examples on (www.sloppycode.net, shameless plug). Remembering the old adage, programming is 90% design, I wrote down the following features I wanted the control to do:
- Auto scrolling
- Target node highlighting when over a node
- Custom cursor when dragging
- Custom ghost icon label when dragging
- Escape key to cancel drag
- Blocks certain nodes from being dragged via a
DragStart event
- Sanity checks for dragging (no parent into children nodes, target isn't the source)
Some of the above features aren't documented in MSDN, but can be found if you trawl through Google groups and websites. I'll go through how I implemented these core features now.
Auto scrolling
This is done via a WinAPI SendMessage call. The OnDragOver event performs a SendMessage call (277 is the constant value, WM_SCROLL I think, but I haven't checked that). This scrolls the treeview up or down, depending on the mouse position.
Target node highlighting
This is pretty straightforward to perform, you simply change the target node's background and foreground color in the OnDragOver event. The default color for this, based on Windows Explorer, is the system 'Highlight' color for the background color, and 'HighlightText' for the foreground color. I've made these properties in the control so people are free to change them to whatever they like.
Custom cursor when dragging
This is done using the OnGiveFeedback event. The event passes a GiveFeedbackEventArgs class which has a UseDefaultCursors property. We can set this to false if we want to implement a custom cursor, and change it to the cursor we want. We also check if dragging is being performed, and change the cursor back if it's not.
Custom ghost icon
This feature is the nicest one of the control, although will probably be the biggest source of bugs. It copies the Windows Explorer behavior of showing the node that is being dragged, as a 'ghosted' or faded out version, including the label of the node and its icon. I implemented this using a second form, which is moved to the position the mouse is. Via properties in the control, you can change the image that is being shown, and the font of the label. It's a nicer version of the custom cursor mentioned above, although I get the feeling I'm doing it a long way round, and that there's a Windows API call that does it for me already - the problem is I don't know what it is. If anyone knows, please say.
Escape key to cancel drag
This is another standard behavior of Windows Explorer's treeview, where you can hit the escape key to cancel the dragging. The OnKeyUp event is where this is performed, it checks to see if the key is the escape key, and cancels the drag if it is, also returning any dragged over nodes to their original state.
Blocks certain nodes from being dragged
I've added a few custom events into the control to add some small extra event functionality. The main one of these is the DragStart event. This is fired when the drag begins, and allows you to check which node is being dragged, and stop the drag drop event if needs be. This can be useful if, for example, you have a recycle bin in your treeview, and don't want the user to be dragging that around the place.
Sanity checks for dragging
This is built in to stop nodes being dragging inside of themselves, or being dragged onto themselves. It uses the Path property to do the check in the fastest way possible. This does mean that if you have 2 paths the same, then it won't work; you may want to build a derived class if you've got this problem, and do it the long way around, by cycling back up the parent nodes and checking it that way.
That's about it. I've added an over-ridden WndProc event which prevents the treeview's background from being repainted on each update, stopping a flicker. It still flickers a bit when you're holding a node, but this seems to be something with the .NET framework controls. Double buffering has been tried but with no success, any suggestions would be welcome.
Hopefully, it'll be useful to some people.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 48 (Total in Forum: 48) (Refresh) | FirstPrevNext |
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
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 (2 votes) |
|
|
|
 |
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
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 (2 votes) |
|
|
|
 |
|
|
 |
|
|
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 (2 votes) |
|
|
|
 |
|
|
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 { /// /// Creates a Cursor from any bitmap. You can use the alpha-channel /// for transparency effects. /// public class BitmapCursor : IDisposable { #region Win-API imports
/// /// API-Structure ICONINFO /// /// [StructLayout(LayoutKind.Sequential)] public struct ICONINFO { public bool fIcon; public uint xHotspot; public uint yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; }
/// /// API function CreateIconIndirect /// [System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern IntPtr CreateIconIndirect( ref ICONINFO iconinfo ); /// /// API function DestryIcon /// [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(); } /// /// Creates a cursor from a bitmap and combines it with another cursor. /// 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(); } }
/// /// destructor /// ~BitmapCursor() { Dispose( false ); } #endregion
#region virtual methods
/// /// clean up resources /// protected virtual void Dispose( bool disposing ) { try { if( handle != IntPtr.Zero ) DestroyIcon( handle ); } catch { } }
#endregion
#region public properties
/// /// The Cursor-Object you can use /// public Cursor Cursor { get { return cursor; } }
#endregion
#region IDisposable Member
/// /// free the used handles /// 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 | 5.00/5 (3 votes) |
|
|
|
 |
|
|
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 { /// /// Creates a Cursor from any bitmap. You can use the alpha-channel /// for transparency effects. /// /// 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. /// public class clsBitmapCursor : IDisposable { #region Win-API imports
/// /// API-Structure ICONINFO /// /// [StructLayout(LayoutKind.Sequential)] public struct ICONINFO { public bool fIcon; public uint xHotspot; public uint yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; }
/// /// API function CreateIconIndirect /// [System.Runtime.InteropServices.DllImport("USER32.DLL")] public static extern IntPtr CreateIconIndirect( ref ICONINFO iconinfo ); /// /// API function DestryIcon /// [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(); }
/// /// destructor /// ~clsBitmapCursor() { Dispose( false ); }
#endregion
/// /// clean up resources /// 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); }
/// /// The Cursor-Object you can use /// public Cursor Cursor { get { return cursor; } }
/// /// free the used handles /// public void Dispose() { GC.SuppressFinalize( this ); Dispose( true ); }
} }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
(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 | |
|
|
|
 |
|
|
Great job with this control.. Just what I was looking for.
However, I'm having trouble with the treeview's width automatically being reduced when a drag event starts.
The problem manifests itself in your demo application if you change the treeview's dock style to none. In my case, I have a treeview and a listview docked to a splitter control, and when I start a drag operation, the treeview's width is reduced so that none of the node captions are visible.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
I'm not quite sure why, but the following line in OnItemDrag:
int width = Width = this._selectedNode.Text.Length * (int) this._formDrag.labelText.Font.Size;
probably should be:
int width = this._selectedNode.Text.Length * (int) this._formDrag.labelText.Font.Size;
It is setting the treeview controls width at the same time as it is assigning the value to the dragged item. This seems to work for me, hopefully it doesn't break anything else!
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
| |