Search code examples
c#objectlistview

ObjectListView is ignoring Dragging effect


Hello I'm using ObjectListView for my application. I try to make a fancy drag effect because the original blue one is not so good. It's like highlighting the first column when I drag. I was using this on my normal listview

        private void lvPlaylist_DragOver(object sender, DragEventArgs e)
        {
            Point mLoc = lvPlaylist.PointToClient(Cursor.Position);
            var hitt = lvPlaylist.HitTest(mLoc);
            if (hitt.Item == null) return;

            int idx = hitt.Item.Index;
            if (idx == prevItem) return;

            lvPlaylist.Refresh();
            using (Graphics g = lvPlaylist.CreateGraphics())
            {
                Rectangle rect = lvPlaylist.GetItemRect(idx);
                Pen MyPen = new Pen(Color.OrangeRed, 3);
                g.DrawLine(MyPen, rect.Left, rect.Top, rect.Right, rect.Top);
            }
            prevItem = idx;
        }

But it's not working in ObjectListView. Well actually it does but when I stop to drag but not releasing my dragging objects it's showing me that blue default drag effect while I keep moving I see my own drag effect. Is there any way to disable OLV Drag effect?


Solution

  • Your solution draws a line above/below the item being selected?

    You can allow dropping between using:

    lvPlaylist.IsSimpleDropSink = true;
    ((SimpleDropSink)lvPlaylist.DropSink).CanDropBetween = true;
    

    If this is not good enough you can respond to ModelCanDrop e.g.

    //((SimpleDropSink)lvPlaylist.DropSink).ModelCanDrop+= ModelCanDrop;
    
     private void ModelCanDrop(object sender, ModelDropEventArgs e)
     {
         e.DropSink.Billboard.BackColor = Color.GreenYellow;
         e.DropSink.FeedbackColor = Color.GreenYellow;
         e.InfoMessage = "Hey there";
         e.Handled = true;
         e.Effect = DragDropEffects.Move;
     }
    

    If you really hate it that much you can even:

    e.DropSink.EnableFeedback = false;
    

    The ObjectListView site has a great indepth tutorial on drag and drop:

    http://objectlistview.sourceforge.net/cs/blog4.html#blog-rearrangingtreelistview

    If you want to go for something really fancy you can write your own subclass for SimpleDropSink:

    lvPlaylist.IsSimpleDragSource = true;
    lvPlaylist.DropSink = new MyDropSink();
    
    private class MyDropSink : SimpleDropSink
    {
        public override void DrawFeedback(Graphics g, Rectangle bounds)
        {
            if(DropTargetLocation != DropTargetLocation.None)
                g.DrawString("Heyyy stuffs happening",new Font(FontFamily.GenericMonospace, 10),new SolidBrush(Color.Magenta),bounds.X,bounds.Y );
        }
    }
    

    For your desired behaviour you should try something like:

    private class MyDropSink : SimpleDropSink
    {
        private ObjectListView _olv;
    
        public MyDropSink(ObjectListView olv)
        {
            _olv = olv;
        }
    
        public override void DrawFeedback(Graphics g, Rectangle bounds)
        {
            if(DropTargetLocation != DropTargetLocation.None)
            {
                Point mLoc = _olv.PointToClient(Cursor.Position);
                var hitt = _olv.HitTest(mLoc);
                if (hitt.Item == null) return;
    
                int idx = hitt.Item.Index;
                Rectangle rect = _olv.GetItemRect(idx);
                Pen MyPen = new Pen(Color.OrangeRed, 3);
                g.DrawLine(MyPen, rect.Left, rect.Top, rect.Right, rect.Top);
            }
        }
    }