Tuesday, September 1, 2009

Reorderable ListView

Demo screenshot


This work just extends another work I found here at CodeProject, and is inspired mainly with the article "Manual reordering of items inside a ListView". What is new in this project is that it is compact (everything needed is part of the inherited control), and that it supports dragging multiple items and automatic scrolling, which I shaped by playlist of Foobar 2000 multimedia player. In this article, I will not describe everything in detail, on the other side I will describe all extended behavior, which I intended to implement.

Drag-drop Construction

As you probably found already, some coders, including MSDN writers, prefer to use built in Drag and Drop methods of ListView to implement Reorder by Mouse function. I found this quite limiting, and bringing no advantages at all. It seems also that we can ask, what does reordering have to do with clipboard. I guess the answer is pretty clear, until you need external data to enter ListView. So I used a method quite similar to that in the referred article. The only thing I changed is that the MouseDown event is not used to initiate Dragging - both: initialization and progress are done in MouseMove. This is also the place where all values which are derived from mouse position are computed. Override WndProc is used to draw insertion line, when Invalidate is called from MouseMove. Finally this event handler is calling autoscroll initializer, which we are always dragging. Of course MouseUp event is used to finalize reordering or eventually to cancel it.

Scrolling Concept

Three images on scrolling principle

Scrolling starts when IsDragging is set to True, and MouseMove occurs in a specified rectangle on top or at the bottom of ListView (Image 1). I defined this area in units of ItemCount, and speed of scrolling is computed from the relative position of mouse to these item sequences. This means that you can set property MaxScrollAreaSize to some count of items, and while your list is high enough to contain this number twice (otherwise Image 2), you can be sure that the control starts to scroll when you place your dragging cursor above this number of items on top or at the bottom of the visible area. Scrolling itself is managed by one routine which computes its parameters from the mouse location, and one timer.

See full detail: http://www.codeproject.com/KB/list/listviewro.aspx

No comments: