/* * DragSource.cs - Add drag source functionality to an ObjectListView * * Author: Phillip Piper * Date: 2009-03-17 5:15 PM * * Change log: * 2011-03-29 JPP - Separate OLVDataObject.cs * v2.3 * 2009-07-06 JPP - Make sure Link is acceptable as an drop effect by default * (since MS didn't make it part of the 'All' value) * v2.2 * 2009-04-15 JPP - Separated DragSource.cs into DropSink.cs * 2009-03-17 JPP - Initial version * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; namespace BrightIdeasSoftware { /// /// An IDragSource controls how drag out from the ObjectListView will behave /// public interface IDragSource { /// /// A drag operation is beginning. Return the data object that will be used /// for data transfer. Return null to prevent the drag from starting. The data /// object will normally include all the selected objects. /// /// /// The returned object is later passed to the GetAllowedEffect() and EndDrag() /// methods. /// /// What ObjectListView is being dragged from. /// Which mouse button is down? /// What item was directly dragged by the user? There may be more than just this /// item selected. /// The data object that will be used for data transfer. This will often be a subclass /// of DataObject, but does not need to be. Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item); /// /// What operations are possible for this drag? This controls the icon shown during the drag /// /// The data object returned by StartDrag() /// A combination of DragDropEffects flags DragDropEffects GetAllowedEffects(Object dragObject); /// /// The drag operation is complete. Do whatever is necessary to complete the action. /// /// The data object returned by StartDrag() /// The value returned from GetAllowedEffects() void EndDrag(Object dragObject, DragDropEffects effect); } /// /// A do-nothing implementation of IDragSource that can be safely subclassed. /// public class AbstractDragSource : IDragSource { #region IDragSource Members /// /// See IDragSource documentation /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { return null; } /// /// See IDragSource documentation /// /// /// public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.None; } /// /// See IDragSource documentation /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { } #endregion } /// /// A reasonable implementation of IDragSource that provides normal /// drag source functionality. It creates a data object that supports /// inter-application dragging of text and HTML representation of /// the dragged rows. It can optionally force a refresh of all dragged /// rows when the drag is complete. /// /// Subclasses can override GetDataObject() to add new /// data formats to the data transfer object. public class SimpleDragSource : IDragSource { #region Constructors /// /// Construct a SimpleDragSource /// public SimpleDragSource() { } /// /// Construct a SimpleDragSource that refreshes the dragged rows when /// the drag is complete /// /// public SimpleDragSource(bool refreshAfterDrop) { this.RefreshAfterDrop = refreshAfterDrop; } #endregion #region Public properties /// /// Gets or sets whether the dragged rows should be refreshed when the /// drag operation is complete. /// public bool RefreshAfterDrop { get { return refreshAfterDrop; } set { refreshAfterDrop = value; } } private bool refreshAfterDrop; #endregion #region IDragSource Members /// /// Create a DataObject when the user does a left mouse drag operation. /// See IDragSource for further information. /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { // We only drag on left mouse if (button != MouseButtons.Left) return null; return this.CreateDataObject(olv); } /// /// Which operations are allowed in the operation? By default, all operations are supported. /// /// /// All opertions are supported public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.All | DragDropEffects.Link; // why didn't MS include 'Link' in 'All'?? } /// /// The drag operation is finished. Refreshe the dragged rows if so configured. /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { OLVDataObject data = dragObject as OLVDataObject; if (data == null) return; if (this.RefreshAfterDrop) data.ListView.RefreshObjects(data.ModelObjects); } /// /// Create a data object that will be used to as the data object /// for the drag operation. /// /// /// Subclasses can override this method add new formats to the data object. /// /// The ObjectListView that is the source of the drag /// A data object for the drag protected virtual object CreateDataObject(ObjectListView olv) { return new OLVDataObject(olv); } #endregion } }